diff options
Diffstat (limited to 'src/tspi')
162 files changed, 55436 insertions, 0 deletions
diff --git a/src/tspi/Makefile.am b/src/tspi/Makefile.am new file mode 100644 index 0000000..6b31e51 --- /dev/null +++ b/src/tspi/Makefile.am @@ -0,0 +1,235 @@ +lib_LTLIBRARIES=libtspi.la + +libtspi_la_LIBADD=${top_builddir}/src/trspi/libtrousers.la + +# On setting -version-info, from the libtool manual: +# +# -version-info current:revision:age +# +# 1. Start with version information of 0:0:0 for each libtool library. +# 2. Update the version information only immediately before a public release of your software. +# More frequent updates are unnecessary, and only guarantee that the current interface +# number gets larger faster. +# 3. If the library source code has changed at all since the last update, then increment +# revision (c:r:a becomes c:r+1:a). +# 4. If any interfaces have been added, removed, or changed since the last update, increment +# current, and set revision to 0. +# 5. If any interfaces have been added since the last public release, then increment age. +# 6. If any interfaces have been removed since the last public release, then set age to 0. + +libtspi_la_LDFLAGS=-version-info 3:0:2 -lpthread @CRYPTOLIB@ + +libtspi_la_CFLAGS=-I$(top_srcdir)/src/include -DAPPID=\"TSPI\" -DVAR_PREFIX=\"@localstatedir@\" -DETC_PREFIX=\"@sysconfdir@\" + +libtspi_la_SOURCES=log.c \ + spi_utils.c \ + obj.c \ + obj_policy.c \ + tsp_policy.c \ + obj_tpm.c \ + obj_context.c \ + tsp_context_mem.c \ + tspi_context.c \ + rpc/@RPC@/rpc_context.c \ + rpc/tcs_api.c \ + rpc/hosttable.c \ + rpc/@RPC@/rpc.c + +if TSS_BUILD_ASYM_CRYPTO +libtspi_la_SOURCES+=tsp_asym.c +endif +if TSS_BUILD_TSS12 +# This is for individual APIs that exist outside TSS 1.2, but may have some TSS 1.2 internal +# features/options such as Tspi_TPM_SetStatus +libtspi_la_SOURCES+=tspi_oper.c tsp_oper.c rpc/@RPC@/rpc_oper.c +libtspi_la_CFLAGS+=-DTSS_BUILD_TSS12 +endif +if TSS_BUILD_TRANSPORT +libtspi_la_SOURCES+=tspi_transport.c rpc/@RPC@/rpc_transport.c +libtspi_la_CFLAGS+=-DTSS_BUILD_TRANSPORT +endif +if TSS_BUILD_TICK +libtspi_la_SOURCES+=tspi_tick.c tsp_tick.c rpc/@RPC@/rpc_tick.c +libtspi_la_CFLAGS+=-DTSS_BUILD_TICK +endif +if TSS_BUILD_COUNTER +libtspi_la_SOURCES+=tspi_counter.c tsp_counter.c rpc/@RPC@/rpc_counter.c +libtspi_la_CFLAGS+=-DTSS_BUILD_COUNTER +endif +if TSS_BUILD_PCR_COMP12 +libtspi_la_SOURCES+=tspi_pcr_comp12.c +endif +if TSS_BUILD_AUTH +libtspi_la_SOURCES+=tsp_auth.c rpc/@RPC@/rpc_auth.c +libtspi_la_CFLAGS+=-DTSS_BUILD_AUTH +endif +if TSS_BUILD_GETSET +libtspi_la_SOURCES+=tspi_getset.c +libtspi_la_CFLAGS+=-DTSS_BUILD_GETSET +endif +if TSS_BUILD_RANDOM +libtspi_la_SOURCES+=tspi_random.c tsp_random.c rpc/@RPC@/rpc_random.c +libtspi_la_CFLAGS+=-DTSS_BUILD_RANDOM +endif +if TSS_BUILD_CAPS +libtspi_la_SOURCES+=tspi_caps.c tsp_caps.c rpc/@RPC@/rpc_caps.c +libtspi_la_CFLAGS+=-DTSS_BUILD_CAPS +endif +if TSS_BUILD_CAPS_TPM +libtspi_la_SOURCES+=tspi_caps_tpm.c tsp_caps_tpm.c rpc/@RPC@/rpc_caps_tpm.c +libtspi_la_CFLAGS+=-DTSS_BUILD_CAPS_TPM +endif +if TSS_BUILD_POLICY +libtspi_la_SOURCES+=tspi_policy.c +libtspi_la_CFLAGS+=-DTSS_BUILD_POLICY +endif +if TSS_BUILD_DIR +libtspi_la_SOURCES+=tspi_dir.c tsp_dir.c rpc/@RPC@/rpc_dir.c +libtspi_la_CFLAGS+=-DTSS_BUILD_DIR +endif +if TSS_BUILD_PCR_EVENTS +libtspi_la_SOURCES+=tspi_pcr_events.c rpc/@RPC@/rpc_evlog.c +libtspi_la_CFLAGS+=-DTSS_BUILD_PCR_EVENTS +endif +if TSS_BUILD_HASH +libtspi_la_SOURCES+=tspi_hash.c +libtspi_la_CFLAGS+=-DTSS_BUILD_HASH +endif +if TSS_BUILD_SIGN +libtspi_la_SOURCES+=tspi_sign.c tsp_sign.c rpc/@RPC@/rpc_sign.c +libtspi_la_CFLAGS+=-DTSS_BUILD_SIGN +endif +if TSS_BUILD_QUOTE +libtspi_la_SOURCES+=tspi_quote.c tsp_quote.c rpc/@RPC@/rpc_quote.c +libtspi_la_CFLAGS+=-DTSS_BUILD_QUOTE +endif +if TSS_BUILD_PCR_COMP +libtspi_la_SOURCES+=tspi_pcr_comp.c +libtspi_la_CFLAGS+=-DTSS_BUILD_PCR_COMP +endif +if TSS_BUILD_SEAL +libtspi_la_SOURCES+=tspi_seal.c rpc/@RPC@/rpc_seal.c +libtspi_la_CFLAGS+=-DTSS_BUILD_SEAL +endif +if TSS_BUILD_CHANGEAUTH +libtspi_la_SOURCES+=tspi_changeauth.c tsp_changeauth.c rpc/@RPC@/rpc_changeauth.c +libtspi_la_CFLAGS+=-DTSS_BUILD_CHANGEAUTH +endif +if TSS_BUILD_BIND +libtspi_la_SOURCES+=tspi_bind.c tsp_bind.c rpc/@RPC@/rpc_bind.c +libtspi_la_CFLAGS+=-DTSS_BUILD_BIND +endif +if TSS_BUILD_OWN +libtspi_la_SOURCES+=tsp_own.c tspi_own.c rpc/@RPC@/rpc_own.c +libtspi_la_CFLAGS+=-DTSS_BUILD_OWN +endif +if TSS_BUILD_PS +libtspi_la_SOURCES+=ps/ps_utils.c ps/tspps.c tspi_ps.c rpc/@RPC@/rpc_ps.c tsp_ps.c +libtspi_la_CFLAGS+=-DTSS_BUILD_PS +endif +if TSS_BUILD_ADMIN +libtspi_la_SOURCES+=tspi_admin.c tsp_admin.c rpc/@RPC@/rpc_admin.c +libtspi_la_CFLAGS+=-DTSS_BUILD_ADMIN +endif +if TSS_BUILD_AIK +libtspi_la_SOURCES+=tspi_aik.c tsp_aik.c rpc/@RPC@/rpc_aik.c +libtspi_la_CFLAGS+=-DTSS_BUILD_AIK +endif +if TSS_BUILD_EK +libtspi_la_SOURCES+=tspi_ek.c tsp_ek.c rpc/@RPC@/rpc_ek.c +libtspi_la_CFLAGS+=-DTSS_BUILD_EK +endif +if TSS_BUILD_CERTIFY +libtspi_la_SOURCES+=tspi_certify.c tsp_certify.c rpc/@RPC@/rpc_certify.c +libtspi_la_CFLAGS+=-DTSS_BUILD_CERTIFY +endif +if TSS_BUILD_KEY +libtspi_la_SOURCES+=tspi_key.c rpc/@RPC@/rpc_key.c +libtspi_la_CFLAGS+=-DTSS_BUILD_KEY +endif +if TSS_BUILD_MAINT +libtspi_la_SOURCES+=tspi_maint.c tsp_maint.c rpc/@RPC@/rpc_maint.c +libtspi_la_CFLAGS+=-DTSS_BUILD_MAINT +endif +if TSS_BUILD_MIGRATION +libtspi_la_SOURCES+=tspi_migration.c tsp_migration.c rpc/@RPC@/rpc_migration.c +libtspi_la_CFLAGS+=-DTSS_BUILD_MIGRATION +endif +if TSS_BUILD_PCR_EXTEND +libtspi_la_SOURCES+=tspi_pcr_extend.c tsp_pcr_extend.c rpc/@RPC@/rpc_pcr_extend.c +libtspi_la_CFLAGS+=-DTSS_BUILD_PCR_EXTEND +endif +if TSS_BUILD_SELFTEST +libtspi_la_SOURCES+=tspi_selftest.c tsp_selftest.c rpc/@RPC@/rpc_selftest.c +libtspi_la_CFLAGS+=-DTSS_BUILD_SELFTEST +endif +if TSS_BUILD_DAA +libtspi_la_SOURCES+=tspi_daa.c tsp_daa.c \ + rpc/@RPC@/rpc_daa.c \ + daa/daa_issuer/keypair_generator.c daa/daa_issuer/prime_gen.c \ + daa/daa_issuer/key_correctness_proof.c daa/daa_platform/platform.c \ + daa/daa_issuer/issuer_init.c daa/daa_issuer/issue_credential.c \ + daa/daa_verifier/verifier_transaction.c daa/daa_verifier/verifier.c \ + daa/daa_structs.c daa/daa_parameter.c daa/big_integer/bi_gmp.c \ + daa/big_integer/bi_openssl.c daa/daa_anonymityrevocation/csencryption_result.c \ + daa/big_integer/bi.c daa/utils/list.c +libtspi_la_CFLAGS+=-DTSS_BUILD_DAA +endif +if TSS_BUILD_GET_FLAGS +libtspi_la_SOURCES+=tsp_get_flags.c +endif +if TSS_BUILD_PCRS_LIST +libtspi_la_SOURCES+=obj_pcrs.c tsp_pcr.c +libtspi_la_CFLAGS+=-DTSS_BUILD_PCRS_LIST +endif +if TSS_BUILD_HASH_LIST +libtspi_la_SOURCES+=obj_hash.c +libtspi_la_CFLAGS+=-DTSS_BUILD_HASH_LIST +endif +if TSS_BUILD_ENCDATA_LIST +libtspi_la_SOURCES+=obj_encdata.c +libtspi_la_CFLAGS+=-DTSS_BUILD_ENCDATA_LIST +endif +if TSS_BUILD_RSAKEY_LIST +libtspi_la_SOURCES+=obj_rsakey.c tsp_key.c +libtspi_la_CFLAGS+=-DTSS_BUILD_RSAKEY_LIST +endif +if TSS_BUILD_ASN1 +libtspi_la_SOURCES+=tspi_asn1.c +libtspi_la_CFLAGS+=-DTSS_BUILD_ASN1 +endif +if TSS_BUILD_AUDIT +libtspi_la_SOURCES+=tspi_audit.c tsp_audit.c rpc/@RPC@/rpc_audit.c +libtspi_la_CFLAGS+=-DTSS_BUILD_AUDIT +endif +if TSS_BUILD_SEALX +libtspi_la_SOURCES+=tsp_seal.c +libtspi_la_CFLAGS+=-DTSS_BUILD_SEALX +endif +if TSS_BUILD_QUOTE2 +libtspi_la_SOURCES+=tspi_quote2.c tsp_quote2.c rpc/@RPC@/rpc_quote2.c +libtspi_la_CFLAGS+=-DTSS_BUILD_QUOTE2 +endif + +if HAVE_GTK +libtspi_la_CFLAGS+=@GTK_CFLAGS@ +libtspi_la_LDFLAGS+=@GTK_LIBS@ +libtspi_la_SOURCES+=gtk/main.c gtk/support.c gtk/interface.c gtk/callbacks.c +endif +if OPENSSL_UI +libtspi_la_LDFLAGS+=-lssl +libtspi_la_SOURCES+=ssl_ui.c +endif + +if TSS_BUILD_NV +libtspi_la_SOURCES+=tspi_nv.c obj_nv.c tsp_nv.c rpc/@RPC@/rpc_nv.c +libtspi_la_CFLAGS+=-DTSS_BUILD_NV +endif +if TSS_BUILD_DELEGATION +libtspi_la_SOURCES+=tspi_delegate.c tsp_delegate.c obj_delfamily.c rpc/@RPC@/rpc_delegate.c +libtspi_la_CFLAGS+=-DTSS_BUILD_DELEGATION +endif +if TSS_BUILD_CMK +libtspi_la_SOURCES+=tspi_cmk.c obj_migdata.c rpc/@RPC@/rpc_cmk.c +libtspi_la_CFLAGS+=-DTSS_BUILD_CMK +endif diff --git a/src/tspi/Makefile.in b/src/tspi/Makefile.in new file mode 100644 index 0000000..1d4bd1d --- /dev/null +++ b/src/tspi/Makefile.in @@ -0,0 +1,2030 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +@TSS_BUILD_ASYM_CRYPTO_TRUE@am__append_1 = tsp_asym.c +# This is for individual APIs that exist outside TSS 1.2, but may have some TSS 1.2 internal +# features/options such as Tspi_TPM_SetStatus +@TSS_BUILD_TSS12_TRUE@am__append_2 = tspi_oper.c tsp_oper.c rpc/@RPC@/rpc_oper.c +@TSS_BUILD_TSS12_TRUE@am__append_3 = -DTSS_BUILD_TSS12 +@TSS_BUILD_TRANSPORT_TRUE@am__append_4 = tspi_transport.c rpc/@RPC@/rpc_transport.c +@TSS_BUILD_TRANSPORT_TRUE@am__append_5 = -DTSS_BUILD_TRANSPORT +@TSS_BUILD_TICK_TRUE@am__append_6 = tspi_tick.c tsp_tick.c rpc/@RPC@/rpc_tick.c +@TSS_BUILD_TICK_TRUE@am__append_7 = -DTSS_BUILD_TICK +@TSS_BUILD_COUNTER_TRUE@am__append_8 = tspi_counter.c tsp_counter.c rpc/@RPC@/rpc_counter.c +@TSS_BUILD_COUNTER_TRUE@am__append_9 = -DTSS_BUILD_COUNTER +@TSS_BUILD_PCR_COMP12_TRUE@am__append_10 = tspi_pcr_comp12.c +@TSS_BUILD_AUTH_TRUE@am__append_11 = tsp_auth.c rpc/@RPC@/rpc_auth.c +@TSS_BUILD_AUTH_TRUE@am__append_12 = -DTSS_BUILD_AUTH +@TSS_BUILD_GETSET_TRUE@am__append_13 = tspi_getset.c +@TSS_BUILD_GETSET_TRUE@am__append_14 = -DTSS_BUILD_GETSET +@TSS_BUILD_RANDOM_TRUE@am__append_15 = tspi_random.c tsp_random.c rpc/@RPC@/rpc_random.c +@TSS_BUILD_RANDOM_TRUE@am__append_16 = -DTSS_BUILD_RANDOM +@TSS_BUILD_CAPS_TRUE@am__append_17 = tspi_caps.c tsp_caps.c rpc/@RPC@/rpc_caps.c +@TSS_BUILD_CAPS_TRUE@am__append_18 = -DTSS_BUILD_CAPS +@TSS_BUILD_CAPS_TPM_TRUE@am__append_19 = tspi_caps_tpm.c tsp_caps_tpm.c rpc/@RPC@/rpc_caps_tpm.c +@TSS_BUILD_CAPS_TPM_TRUE@am__append_20 = -DTSS_BUILD_CAPS_TPM +@TSS_BUILD_POLICY_TRUE@am__append_21 = tspi_policy.c +@TSS_BUILD_POLICY_TRUE@am__append_22 = -DTSS_BUILD_POLICY +@TSS_BUILD_DIR_TRUE@am__append_23 = tspi_dir.c tsp_dir.c rpc/@RPC@/rpc_dir.c +@TSS_BUILD_DIR_TRUE@am__append_24 = -DTSS_BUILD_DIR +@TSS_BUILD_PCR_EVENTS_TRUE@am__append_25 = tspi_pcr_events.c rpc/@RPC@/rpc_evlog.c +@TSS_BUILD_PCR_EVENTS_TRUE@am__append_26 = -DTSS_BUILD_PCR_EVENTS +@TSS_BUILD_HASH_TRUE@am__append_27 = tspi_hash.c +@TSS_BUILD_HASH_TRUE@am__append_28 = -DTSS_BUILD_HASH +@TSS_BUILD_SIGN_TRUE@am__append_29 = tspi_sign.c tsp_sign.c rpc/@RPC@/rpc_sign.c +@TSS_BUILD_SIGN_TRUE@am__append_30 = -DTSS_BUILD_SIGN +@TSS_BUILD_QUOTE_TRUE@am__append_31 = tspi_quote.c tsp_quote.c rpc/@RPC@/rpc_quote.c +@TSS_BUILD_QUOTE_TRUE@am__append_32 = -DTSS_BUILD_QUOTE +@TSS_BUILD_PCR_COMP_TRUE@am__append_33 = tspi_pcr_comp.c +@TSS_BUILD_PCR_COMP_TRUE@am__append_34 = -DTSS_BUILD_PCR_COMP +@TSS_BUILD_SEAL_TRUE@am__append_35 = tspi_seal.c rpc/@RPC@/rpc_seal.c +@TSS_BUILD_SEAL_TRUE@am__append_36 = -DTSS_BUILD_SEAL +@TSS_BUILD_CHANGEAUTH_TRUE@am__append_37 = tspi_changeauth.c tsp_changeauth.c rpc/@RPC@/rpc_changeauth.c +@TSS_BUILD_CHANGEAUTH_TRUE@am__append_38 = -DTSS_BUILD_CHANGEAUTH +@TSS_BUILD_BIND_TRUE@am__append_39 = tspi_bind.c tsp_bind.c rpc/@RPC@/rpc_bind.c +@TSS_BUILD_BIND_TRUE@am__append_40 = -DTSS_BUILD_BIND +@TSS_BUILD_OWN_TRUE@am__append_41 = tsp_own.c tspi_own.c rpc/@RPC@/rpc_own.c +@TSS_BUILD_OWN_TRUE@am__append_42 = -DTSS_BUILD_OWN +@TSS_BUILD_PS_TRUE@am__append_43 = ps/ps_utils.c ps/tspps.c tspi_ps.c rpc/@RPC@/rpc_ps.c tsp_ps.c +@TSS_BUILD_PS_TRUE@am__append_44 = -DTSS_BUILD_PS +@TSS_BUILD_ADMIN_TRUE@am__append_45 = tspi_admin.c tsp_admin.c rpc/@RPC@/rpc_admin.c +@TSS_BUILD_ADMIN_TRUE@am__append_46 = -DTSS_BUILD_ADMIN +@TSS_BUILD_AIK_TRUE@am__append_47 = tspi_aik.c tsp_aik.c rpc/@RPC@/rpc_aik.c +@TSS_BUILD_AIK_TRUE@am__append_48 = -DTSS_BUILD_AIK +@TSS_BUILD_EK_TRUE@am__append_49 = tspi_ek.c tsp_ek.c rpc/@RPC@/rpc_ek.c +@TSS_BUILD_EK_TRUE@am__append_50 = -DTSS_BUILD_EK +@TSS_BUILD_CERTIFY_TRUE@am__append_51 = tspi_certify.c tsp_certify.c rpc/@RPC@/rpc_certify.c +@TSS_BUILD_CERTIFY_TRUE@am__append_52 = -DTSS_BUILD_CERTIFY +@TSS_BUILD_KEY_TRUE@am__append_53 = tspi_key.c rpc/@RPC@/rpc_key.c +@TSS_BUILD_KEY_TRUE@am__append_54 = -DTSS_BUILD_KEY +@TSS_BUILD_MAINT_TRUE@am__append_55 = tspi_maint.c tsp_maint.c rpc/@RPC@/rpc_maint.c +@TSS_BUILD_MAINT_TRUE@am__append_56 = -DTSS_BUILD_MAINT +@TSS_BUILD_MIGRATION_TRUE@am__append_57 = tspi_migration.c tsp_migration.c rpc/@RPC@/rpc_migration.c +@TSS_BUILD_MIGRATION_TRUE@am__append_58 = -DTSS_BUILD_MIGRATION +@TSS_BUILD_PCR_EXTEND_TRUE@am__append_59 = tspi_pcr_extend.c tsp_pcr_extend.c rpc/@RPC@/rpc_pcr_extend.c +@TSS_BUILD_PCR_EXTEND_TRUE@am__append_60 = -DTSS_BUILD_PCR_EXTEND +@TSS_BUILD_SELFTEST_TRUE@am__append_61 = tspi_selftest.c tsp_selftest.c rpc/@RPC@/rpc_selftest.c +@TSS_BUILD_SELFTEST_TRUE@am__append_62 = -DTSS_BUILD_SELFTEST +@TSS_BUILD_DAA_TRUE@am__append_63 = tspi_daa.c tsp_daa.c \ +@TSS_BUILD_DAA_TRUE@ rpc/@RPC@/rpc_daa.c \ +@TSS_BUILD_DAA_TRUE@ daa/daa_issuer/keypair_generator.c daa/daa_issuer/prime_gen.c \ +@TSS_BUILD_DAA_TRUE@ daa/daa_issuer/key_correctness_proof.c daa/daa_platform/platform.c \ +@TSS_BUILD_DAA_TRUE@ daa/daa_issuer/issuer_init.c daa/daa_issuer/issue_credential.c \ +@TSS_BUILD_DAA_TRUE@ daa/daa_verifier/verifier_transaction.c daa/daa_verifier/verifier.c \ +@TSS_BUILD_DAA_TRUE@ daa/daa_structs.c daa/daa_parameter.c daa/big_integer/bi_gmp.c \ +@TSS_BUILD_DAA_TRUE@ daa/big_integer/bi_openssl.c daa/daa_anonymityrevocation/csencryption_result.c \ +@TSS_BUILD_DAA_TRUE@ daa/big_integer/bi.c daa/utils/list.c + +@TSS_BUILD_DAA_TRUE@am__append_64 = -DTSS_BUILD_DAA +@TSS_BUILD_GET_FLAGS_TRUE@am__append_65 = tsp_get_flags.c +@TSS_BUILD_PCRS_LIST_TRUE@am__append_66 = obj_pcrs.c tsp_pcr.c +@TSS_BUILD_PCRS_LIST_TRUE@am__append_67 = -DTSS_BUILD_PCRS_LIST +@TSS_BUILD_HASH_LIST_TRUE@am__append_68 = obj_hash.c +@TSS_BUILD_HASH_LIST_TRUE@am__append_69 = -DTSS_BUILD_HASH_LIST +@TSS_BUILD_ENCDATA_LIST_TRUE@am__append_70 = obj_encdata.c +@TSS_BUILD_ENCDATA_LIST_TRUE@am__append_71 = -DTSS_BUILD_ENCDATA_LIST +@TSS_BUILD_RSAKEY_LIST_TRUE@am__append_72 = obj_rsakey.c tsp_key.c +@TSS_BUILD_RSAKEY_LIST_TRUE@am__append_73 = -DTSS_BUILD_RSAKEY_LIST +@TSS_BUILD_ASN1_TRUE@am__append_74 = tspi_asn1.c +@TSS_BUILD_ASN1_TRUE@am__append_75 = -DTSS_BUILD_ASN1 +@TSS_BUILD_AUDIT_TRUE@am__append_76 = tspi_audit.c tsp_audit.c rpc/@RPC@/rpc_audit.c +@TSS_BUILD_AUDIT_TRUE@am__append_77 = -DTSS_BUILD_AUDIT +@TSS_BUILD_SEALX_TRUE@am__append_78 = tsp_seal.c +@TSS_BUILD_SEALX_TRUE@am__append_79 = -DTSS_BUILD_SEALX +@TSS_BUILD_QUOTE2_TRUE@am__append_80 = tspi_quote2.c tsp_quote2.c rpc/@RPC@/rpc_quote2.c +@TSS_BUILD_QUOTE2_TRUE@am__append_81 = -DTSS_BUILD_QUOTE2 +@HAVE_GTK_TRUE@am__append_82 = @GTK_CFLAGS@ +@HAVE_GTK_TRUE@am__append_83 = @GTK_LIBS@ +@HAVE_GTK_TRUE@am__append_84 = gtk/main.c gtk/support.c gtk/interface.c gtk/callbacks.c +@OPENSSL_UI_TRUE@am__append_85 = -lssl +@OPENSSL_UI_TRUE@am__append_86 = ssl_ui.c +@TSS_BUILD_NV_TRUE@am__append_87 = tspi_nv.c obj_nv.c tsp_nv.c rpc/@RPC@/rpc_nv.c +@TSS_BUILD_NV_TRUE@am__append_88 = -DTSS_BUILD_NV +@TSS_BUILD_DELEGATION_TRUE@am__append_89 = tspi_delegate.c tsp_delegate.c obj_delfamily.c rpc/@RPC@/rpc_delegate.c +@TSS_BUILD_DELEGATION_TRUE@am__append_90 = -DTSS_BUILD_DELEGATION +@TSS_BUILD_CMK_TRUE@am__append_91 = tspi_cmk.c obj_migdata.c rpc/@RPC@/rpc_cmk.c +@TSS_BUILD_CMK_TRUE@am__append_92 = -DTSS_BUILD_CMK +subdir = src/tspi +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libtspi_la_DEPENDENCIES = ${top_builddir}/src/trspi/libtrousers.la +am__libtspi_la_SOURCES_DIST = log.c spi_utils.c obj.c obj_policy.c \ + tsp_policy.c obj_tpm.c obj_context.c tsp_context_mem.c \ + tspi_context.c rpc/@RPC@/rpc_context.c rpc/tcs_api.c \ + rpc/hosttable.c rpc/@RPC@/rpc.c tsp_asym.c tspi_oper.c \ + tsp_oper.c rpc/@RPC@/rpc_oper.c tspi_transport.c \ + rpc/@RPC@/rpc_transport.c tspi_tick.c tsp_tick.c \ + rpc/@RPC@/rpc_tick.c tspi_counter.c tsp_counter.c \ + rpc/@RPC@/rpc_counter.c tspi_pcr_comp12.c tsp_auth.c \ + rpc/@RPC@/rpc_auth.c tspi_getset.c tspi_random.c tsp_random.c \ + rpc/@RPC@/rpc_random.c tspi_caps.c tsp_caps.c \ + rpc/@RPC@/rpc_caps.c tspi_caps_tpm.c tsp_caps_tpm.c \ + rpc/@RPC@/rpc_caps_tpm.c tspi_policy.c tspi_dir.c tsp_dir.c \ + rpc/@RPC@/rpc_dir.c tspi_pcr_events.c rpc/@RPC@/rpc_evlog.c \ + tspi_hash.c tspi_sign.c tsp_sign.c rpc/@RPC@/rpc_sign.c \ + tspi_quote.c tsp_quote.c rpc/@RPC@/rpc_quote.c tspi_pcr_comp.c \ + tspi_seal.c rpc/@RPC@/rpc_seal.c tspi_changeauth.c \ + tsp_changeauth.c rpc/@RPC@/rpc_changeauth.c tspi_bind.c \ + tsp_bind.c rpc/@RPC@/rpc_bind.c tsp_own.c tspi_own.c \ + rpc/@RPC@/rpc_own.c ps/ps_utils.c ps/tspps.c tspi_ps.c \ + rpc/@RPC@/rpc_ps.c tsp_ps.c tspi_admin.c tsp_admin.c \ + rpc/@RPC@/rpc_admin.c tspi_aik.c tsp_aik.c rpc/@RPC@/rpc_aik.c \ + tspi_ek.c tsp_ek.c rpc/@RPC@/rpc_ek.c tspi_certify.c \ + tsp_certify.c rpc/@RPC@/rpc_certify.c tspi_key.c \ + rpc/@RPC@/rpc_key.c tspi_maint.c tsp_maint.c \ + rpc/@RPC@/rpc_maint.c tspi_migration.c tsp_migration.c \ + rpc/@RPC@/rpc_migration.c tspi_pcr_extend.c tsp_pcr_extend.c \ + rpc/@RPC@/rpc_pcr_extend.c tspi_selftest.c tsp_selftest.c \ + rpc/@RPC@/rpc_selftest.c tspi_daa.c tsp_daa.c \ + rpc/@RPC@/rpc_daa.c daa/daa_issuer/keypair_generator.c \ + daa/daa_issuer/prime_gen.c \ + daa/daa_issuer/key_correctness_proof.c \ + daa/daa_platform/platform.c daa/daa_issuer/issuer_init.c \ + daa/daa_issuer/issue_credential.c \ + daa/daa_verifier/verifier_transaction.c \ + daa/daa_verifier/verifier.c daa/daa_structs.c \ + daa/daa_parameter.c daa/big_integer/bi_gmp.c \ + daa/big_integer/bi_openssl.c \ + daa/daa_anonymityrevocation/csencryption_result.c \ + daa/big_integer/bi.c daa/utils/list.c tsp_get_flags.c \ + obj_pcrs.c tsp_pcr.c obj_hash.c obj_encdata.c obj_rsakey.c \ + tsp_key.c tspi_asn1.c tspi_audit.c tsp_audit.c \ + rpc/@RPC@/rpc_audit.c tsp_seal.c tspi_quote2.c tsp_quote2.c \ + rpc/@RPC@/rpc_quote2.c gtk/main.c gtk/support.c \ + gtk/interface.c gtk/callbacks.c ssl_ui.c tspi_nv.c obj_nv.c \ + tsp_nv.c rpc/@RPC@/rpc_nv.c tspi_delegate.c tsp_delegate.c \ + obj_delfamily.c rpc/@RPC@/rpc_delegate.c tspi_cmk.c \ + obj_migdata.c rpc/@RPC@/rpc_cmk.c +@TSS_BUILD_ASYM_CRYPTO_TRUE@am__objects_1 = libtspi_la-tsp_asym.lo +@TSS_BUILD_TSS12_TRUE@am__objects_2 = libtspi_la-tspi_oper.lo \ +@TSS_BUILD_TSS12_TRUE@ libtspi_la-tsp_oper.lo \ +@TSS_BUILD_TSS12_TRUE@ libtspi_la-rpc_oper.lo +@TSS_BUILD_TRANSPORT_TRUE@am__objects_3 = \ +@TSS_BUILD_TRANSPORT_TRUE@ libtspi_la-tspi_transport.lo \ +@TSS_BUILD_TRANSPORT_TRUE@ libtspi_la-rpc_transport.lo +@TSS_BUILD_TICK_TRUE@am__objects_4 = libtspi_la-tspi_tick.lo \ +@TSS_BUILD_TICK_TRUE@ libtspi_la-tsp_tick.lo \ +@TSS_BUILD_TICK_TRUE@ libtspi_la-rpc_tick.lo +@TSS_BUILD_COUNTER_TRUE@am__objects_5 = libtspi_la-tspi_counter.lo \ +@TSS_BUILD_COUNTER_TRUE@ libtspi_la-tsp_counter.lo \ +@TSS_BUILD_COUNTER_TRUE@ libtspi_la-rpc_counter.lo +@TSS_BUILD_PCR_COMP12_TRUE@am__objects_6 = \ +@TSS_BUILD_PCR_COMP12_TRUE@ libtspi_la-tspi_pcr_comp12.lo +@TSS_BUILD_AUTH_TRUE@am__objects_7 = libtspi_la-tsp_auth.lo \ +@TSS_BUILD_AUTH_TRUE@ libtspi_la-rpc_auth.lo +@TSS_BUILD_GETSET_TRUE@am__objects_8 = libtspi_la-tspi_getset.lo +@TSS_BUILD_RANDOM_TRUE@am__objects_9 = libtspi_la-tspi_random.lo \ +@TSS_BUILD_RANDOM_TRUE@ libtspi_la-tsp_random.lo \ +@TSS_BUILD_RANDOM_TRUE@ libtspi_la-rpc_random.lo +@TSS_BUILD_CAPS_TRUE@am__objects_10 = libtspi_la-tspi_caps.lo \ +@TSS_BUILD_CAPS_TRUE@ libtspi_la-tsp_caps.lo \ +@TSS_BUILD_CAPS_TRUE@ libtspi_la-rpc_caps.lo +@TSS_BUILD_CAPS_TPM_TRUE@am__objects_11 = libtspi_la-tspi_caps_tpm.lo \ +@TSS_BUILD_CAPS_TPM_TRUE@ libtspi_la-tsp_caps_tpm.lo \ +@TSS_BUILD_CAPS_TPM_TRUE@ libtspi_la-rpc_caps_tpm.lo +@TSS_BUILD_POLICY_TRUE@am__objects_12 = libtspi_la-tspi_policy.lo +@TSS_BUILD_DIR_TRUE@am__objects_13 = libtspi_la-tspi_dir.lo \ +@TSS_BUILD_DIR_TRUE@ libtspi_la-tsp_dir.lo \ +@TSS_BUILD_DIR_TRUE@ libtspi_la-rpc_dir.lo +@TSS_BUILD_PCR_EVENTS_TRUE@am__objects_14 = \ +@TSS_BUILD_PCR_EVENTS_TRUE@ libtspi_la-tspi_pcr_events.lo \ +@TSS_BUILD_PCR_EVENTS_TRUE@ libtspi_la-rpc_evlog.lo +@TSS_BUILD_HASH_TRUE@am__objects_15 = libtspi_la-tspi_hash.lo +@TSS_BUILD_SIGN_TRUE@am__objects_16 = libtspi_la-tspi_sign.lo \ +@TSS_BUILD_SIGN_TRUE@ libtspi_la-tsp_sign.lo \ +@TSS_BUILD_SIGN_TRUE@ libtspi_la-rpc_sign.lo +@TSS_BUILD_QUOTE_TRUE@am__objects_17 = libtspi_la-tspi_quote.lo \ +@TSS_BUILD_QUOTE_TRUE@ libtspi_la-tsp_quote.lo \ +@TSS_BUILD_QUOTE_TRUE@ libtspi_la-rpc_quote.lo +@TSS_BUILD_PCR_COMP_TRUE@am__objects_18 = libtspi_la-tspi_pcr_comp.lo +@TSS_BUILD_SEAL_TRUE@am__objects_19 = libtspi_la-tspi_seal.lo \ +@TSS_BUILD_SEAL_TRUE@ libtspi_la-rpc_seal.lo +@TSS_BUILD_CHANGEAUTH_TRUE@am__objects_20 = \ +@TSS_BUILD_CHANGEAUTH_TRUE@ libtspi_la-tspi_changeauth.lo \ +@TSS_BUILD_CHANGEAUTH_TRUE@ libtspi_la-tsp_changeauth.lo \ +@TSS_BUILD_CHANGEAUTH_TRUE@ libtspi_la-rpc_changeauth.lo +@TSS_BUILD_BIND_TRUE@am__objects_21 = libtspi_la-tspi_bind.lo \ +@TSS_BUILD_BIND_TRUE@ libtspi_la-tsp_bind.lo \ +@TSS_BUILD_BIND_TRUE@ libtspi_la-rpc_bind.lo +@TSS_BUILD_OWN_TRUE@am__objects_22 = libtspi_la-tsp_own.lo \ +@TSS_BUILD_OWN_TRUE@ libtspi_la-tspi_own.lo \ +@TSS_BUILD_OWN_TRUE@ libtspi_la-rpc_own.lo +@TSS_BUILD_PS_TRUE@am__objects_23 = libtspi_la-ps_utils.lo \ +@TSS_BUILD_PS_TRUE@ libtspi_la-tspps.lo libtspi_la-tspi_ps.lo \ +@TSS_BUILD_PS_TRUE@ libtspi_la-rpc_ps.lo libtspi_la-tsp_ps.lo +@TSS_BUILD_ADMIN_TRUE@am__objects_24 = libtspi_la-tspi_admin.lo \ +@TSS_BUILD_ADMIN_TRUE@ libtspi_la-tsp_admin.lo \ +@TSS_BUILD_ADMIN_TRUE@ libtspi_la-rpc_admin.lo +@TSS_BUILD_AIK_TRUE@am__objects_25 = libtspi_la-tspi_aik.lo \ +@TSS_BUILD_AIK_TRUE@ libtspi_la-tsp_aik.lo \ +@TSS_BUILD_AIK_TRUE@ libtspi_la-rpc_aik.lo +@TSS_BUILD_EK_TRUE@am__objects_26 = libtspi_la-tspi_ek.lo \ +@TSS_BUILD_EK_TRUE@ libtspi_la-tsp_ek.lo libtspi_la-rpc_ek.lo +@TSS_BUILD_CERTIFY_TRUE@am__objects_27 = libtspi_la-tspi_certify.lo \ +@TSS_BUILD_CERTIFY_TRUE@ libtspi_la-tsp_certify.lo \ +@TSS_BUILD_CERTIFY_TRUE@ libtspi_la-rpc_certify.lo +@TSS_BUILD_KEY_TRUE@am__objects_28 = libtspi_la-tspi_key.lo \ +@TSS_BUILD_KEY_TRUE@ libtspi_la-rpc_key.lo +@TSS_BUILD_MAINT_TRUE@am__objects_29 = libtspi_la-tspi_maint.lo \ +@TSS_BUILD_MAINT_TRUE@ libtspi_la-tsp_maint.lo \ +@TSS_BUILD_MAINT_TRUE@ libtspi_la-rpc_maint.lo +@TSS_BUILD_MIGRATION_TRUE@am__objects_30 = \ +@TSS_BUILD_MIGRATION_TRUE@ libtspi_la-tspi_migration.lo \ +@TSS_BUILD_MIGRATION_TRUE@ libtspi_la-tsp_migration.lo \ +@TSS_BUILD_MIGRATION_TRUE@ libtspi_la-rpc_migration.lo +@TSS_BUILD_PCR_EXTEND_TRUE@am__objects_31 = \ +@TSS_BUILD_PCR_EXTEND_TRUE@ libtspi_la-tspi_pcr_extend.lo \ +@TSS_BUILD_PCR_EXTEND_TRUE@ libtspi_la-tsp_pcr_extend.lo \ +@TSS_BUILD_PCR_EXTEND_TRUE@ libtspi_la-rpc_pcr_extend.lo +@TSS_BUILD_SELFTEST_TRUE@am__objects_32 = libtspi_la-tspi_selftest.lo \ +@TSS_BUILD_SELFTEST_TRUE@ libtspi_la-tsp_selftest.lo \ +@TSS_BUILD_SELFTEST_TRUE@ libtspi_la-rpc_selftest.lo +@TSS_BUILD_DAA_TRUE@am__objects_33 = libtspi_la-tspi_daa.lo \ +@TSS_BUILD_DAA_TRUE@ libtspi_la-tsp_daa.lo \ +@TSS_BUILD_DAA_TRUE@ libtspi_la-rpc_daa.lo \ +@TSS_BUILD_DAA_TRUE@ libtspi_la-keypair_generator.lo \ +@TSS_BUILD_DAA_TRUE@ libtspi_la-prime_gen.lo \ +@TSS_BUILD_DAA_TRUE@ libtspi_la-key_correctness_proof.lo \ +@TSS_BUILD_DAA_TRUE@ libtspi_la-platform.lo \ +@TSS_BUILD_DAA_TRUE@ libtspi_la-issuer_init.lo \ +@TSS_BUILD_DAA_TRUE@ libtspi_la-issue_credential.lo \ +@TSS_BUILD_DAA_TRUE@ libtspi_la-verifier_transaction.lo \ +@TSS_BUILD_DAA_TRUE@ libtspi_la-verifier.lo \ +@TSS_BUILD_DAA_TRUE@ libtspi_la-daa_structs.lo \ +@TSS_BUILD_DAA_TRUE@ libtspi_la-daa_parameter.lo \ +@TSS_BUILD_DAA_TRUE@ libtspi_la-bi_gmp.lo \ +@TSS_BUILD_DAA_TRUE@ libtspi_la-bi_openssl.lo \ +@TSS_BUILD_DAA_TRUE@ libtspi_la-csencryption_result.lo \ +@TSS_BUILD_DAA_TRUE@ libtspi_la-bi.lo libtspi_la-list.lo +@TSS_BUILD_GET_FLAGS_TRUE@am__objects_34 = \ +@TSS_BUILD_GET_FLAGS_TRUE@ libtspi_la-tsp_get_flags.lo +@TSS_BUILD_PCRS_LIST_TRUE@am__objects_35 = libtspi_la-obj_pcrs.lo \ +@TSS_BUILD_PCRS_LIST_TRUE@ libtspi_la-tsp_pcr.lo +@TSS_BUILD_HASH_LIST_TRUE@am__objects_36 = libtspi_la-obj_hash.lo +@TSS_BUILD_ENCDATA_LIST_TRUE@am__objects_37 = \ +@TSS_BUILD_ENCDATA_LIST_TRUE@ libtspi_la-obj_encdata.lo +@TSS_BUILD_RSAKEY_LIST_TRUE@am__objects_38 = libtspi_la-obj_rsakey.lo \ +@TSS_BUILD_RSAKEY_LIST_TRUE@ libtspi_la-tsp_key.lo +@TSS_BUILD_ASN1_TRUE@am__objects_39 = libtspi_la-tspi_asn1.lo +@TSS_BUILD_AUDIT_TRUE@am__objects_40 = libtspi_la-tspi_audit.lo \ +@TSS_BUILD_AUDIT_TRUE@ libtspi_la-tsp_audit.lo \ +@TSS_BUILD_AUDIT_TRUE@ libtspi_la-rpc_audit.lo +@TSS_BUILD_SEALX_TRUE@am__objects_41 = libtspi_la-tsp_seal.lo +@TSS_BUILD_QUOTE2_TRUE@am__objects_42 = libtspi_la-tspi_quote2.lo \ +@TSS_BUILD_QUOTE2_TRUE@ libtspi_la-tsp_quote2.lo \ +@TSS_BUILD_QUOTE2_TRUE@ libtspi_la-rpc_quote2.lo +@HAVE_GTK_TRUE@am__objects_43 = libtspi_la-main.lo \ +@HAVE_GTK_TRUE@ libtspi_la-support.lo libtspi_la-interface.lo \ +@HAVE_GTK_TRUE@ libtspi_la-callbacks.lo +@OPENSSL_UI_TRUE@am__objects_44 = libtspi_la-ssl_ui.lo +@TSS_BUILD_NV_TRUE@am__objects_45 = libtspi_la-tspi_nv.lo \ +@TSS_BUILD_NV_TRUE@ libtspi_la-obj_nv.lo libtspi_la-tsp_nv.lo \ +@TSS_BUILD_NV_TRUE@ libtspi_la-rpc_nv.lo +@TSS_BUILD_DELEGATION_TRUE@am__objects_46 = \ +@TSS_BUILD_DELEGATION_TRUE@ libtspi_la-tspi_delegate.lo \ +@TSS_BUILD_DELEGATION_TRUE@ libtspi_la-tsp_delegate.lo \ +@TSS_BUILD_DELEGATION_TRUE@ libtspi_la-obj_delfamily.lo \ +@TSS_BUILD_DELEGATION_TRUE@ libtspi_la-rpc_delegate.lo +@TSS_BUILD_CMK_TRUE@am__objects_47 = libtspi_la-tspi_cmk.lo \ +@TSS_BUILD_CMK_TRUE@ libtspi_la-obj_migdata.lo \ +@TSS_BUILD_CMK_TRUE@ libtspi_la-rpc_cmk.lo +am_libtspi_la_OBJECTS = libtspi_la-log.lo libtspi_la-spi_utils.lo \ + libtspi_la-obj.lo libtspi_la-obj_policy.lo \ + libtspi_la-tsp_policy.lo libtspi_la-obj_tpm.lo \ + libtspi_la-obj_context.lo libtspi_la-tsp_context_mem.lo \ + libtspi_la-tspi_context.lo libtspi_la-rpc_context.lo \ + libtspi_la-tcs_api.lo libtspi_la-hosttable.lo \ + libtspi_la-rpc.lo $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) $(am__objects_4) $(am__objects_5) \ + $(am__objects_6) $(am__objects_7) $(am__objects_8) \ + $(am__objects_9) $(am__objects_10) $(am__objects_11) \ + $(am__objects_12) $(am__objects_13) $(am__objects_14) \ + $(am__objects_15) $(am__objects_16) $(am__objects_17) \ + $(am__objects_18) $(am__objects_19) $(am__objects_20) \ + $(am__objects_21) $(am__objects_22) $(am__objects_23) \ + $(am__objects_24) $(am__objects_25) $(am__objects_26) \ + $(am__objects_27) $(am__objects_28) $(am__objects_29) \ + $(am__objects_30) $(am__objects_31) $(am__objects_32) \ + $(am__objects_33) $(am__objects_34) $(am__objects_35) \ + $(am__objects_36) $(am__objects_37) $(am__objects_38) \ + $(am__objects_39) $(am__objects_40) $(am__objects_41) \ + $(am__objects_42) $(am__objects_43) $(am__objects_44) \ + $(am__objects_45) $(am__objects_46) $(am__objects_47) +libtspi_la_OBJECTS = $(am_libtspi_la_OBJECTS) +libtspi_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libtspi_la_CFLAGS) \ + $(CFLAGS) $(libtspi_la_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libtspi_la_SOURCES) +DIST_SOURCES = $(am__libtspi_la_SOURCES_DIST) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CRYPTOLIB = @CRYPTOLIB@ +CRYPTO_PACKAGE = @CRYPTO_PACKAGE@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_LIBS = @GTK_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_LIB_DIR = @OPENSSL_LIB_DIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +RPC = @RPC@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TCSD_DEFAULT_PORT = @TCSD_DEFAULT_PORT@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +lib_LTLIBRARIES = libtspi.la +libtspi_la_LIBADD = ${top_builddir}/src/trspi/libtrousers.la + +# On setting -version-info, from the libtool manual: +# +# -version-info current:revision:age +# +# 1. Start with version information of 0:0:0 for each libtool library. +# 2. Update the version information only immediately before a public release of your software. +# More frequent updates are unnecessary, and only guarantee that the current interface +# number gets larger faster. +# 3. If the library source code has changed at all since the last update, then increment +# revision (c:r:a becomes c:r+1:a). +# 4. If any interfaces have been added, removed, or changed since the last update, increment +# current, and set revision to 0. +# 5. If any interfaces have been added since the last public release, then increment age. +# 6. If any interfaces have been removed since the last public release, then set age to 0. +libtspi_la_LDFLAGS = -version-info 3:0:2 -lpthread @CRYPTOLIB@ \ + $(am__append_83) $(am__append_85) +libtspi_la_CFLAGS = -I$(top_srcdir)/src/include -DAPPID=\"TSPI\" \ + -DVAR_PREFIX=\"@localstatedir@\" -DETC_PREFIX=\"@sysconfdir@\" \ + $(am__append_3) $(am__append_5) $(am__append_7) \ + $(am__append_9) $(am__append_12) $(am__append_14) \ + $(am__append_16) $(am__append_18) $(am__append_20) \ + $(am__append_22) $(am__append_24) $(am__append_26) \ + $(am__append_28) $(am__append_30) $(am__append_32) \ + $(am__append_34) $(am__append_36) $(am__append_38) \ + $(am__append_40) $(am__append_42) $(am__append_44) \ + $(am__append_46) $(am__append_48) $(am__append_50) \ + $(am__append_52) $(am__append_54) $(am__append_56) \ + $(am__append_58) $(am__append_60) $(am__append_62) \ + $(am__append_64) $(am__append_67) $(am__append_69) \ + $(am__append_71) $(am__append_73) $(am__append_75) \ + $(am__append_77) $(am__append_79) $(am__append_81) \ + $(am__append_82) $(am__append_88) $(am__append_90) \ + $(am__append_92) +libtspi_la_SOURCES = log.c spi_utils.c obj.c obj_policy.c tsp_policy.c \ + obj_tpm.c obj_context.c tsp_context_mem.c tspi_context.c \ + rpc/@RPC@/rpc_context.c rpc/tcs_api.c rpc/hosttable.c \ + rpc/@RPC@/rpc.c $(am__append_1) $(am__append_2) \ + $(am__append_4) $(am__append_6) $(am__append_8) \ + $(am__append_10) $(am__append_11) $(am__append_13) \ + $(am__append_15) $(am__append_17) $(am__append_19) \ + $(am__append_21) $(am__append_23) $(am__append_25) \ + $(am__append_27) $(am__append_29) $(am__append_31) \ + $(am__append_33) $(am__append_35) $(am__append_37) \ + $(am__append_39) $(am__append_41) $(am__append_43) \ + $(am__append_45) $(am__append_47) $(am__append_49) \ + $(am__append_51) $(am__append_53) $(am__append_55) \ + $(am__append_57) $(am__append_59) $(am__append_61) \ + $(am__append_63) $(am__append_65) $(am__append_66) \ + $(am__append_68) $(am__append_70) $(am__append_72) \ + $(am__append_74) $(am__append_76) $(am__append_78) \ + $(am__append_80) $(am__append_84) $(am__append_86) \ + $(am__append_87) $(am__append_89) $(am__append_91) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/tspi/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/tspi/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libtspi.la: $(libtspi_la_OBJECTS) $(libtspi_la_DEPENDENCIES) + $(libtspi_la_LINK) -rpath $(libdir) $(libtspi_la_OBJECTS) $(libtspi_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-bi.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-bi_gmp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-bi_openssl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-callbacks.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-csencryption_result.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-daa_parameter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-daa_structs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-hosttable.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-interface.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-issue_credential.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-issuer_init.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-key_correctness_proof.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-keypair_generator.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-list.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-log.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-main.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-obj.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-obj_context.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-obj_delfamily.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-obj_encdata.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-obj_hash.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-obj_migdata.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-obj_nv.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-obj_pcrs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-obj_policy.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-obj_rsakey.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-obj_tpm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-platform.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-prime_gen.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-ps_utils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_admin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_aik.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_audit.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_auth.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_bind.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_caps.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_caps_tpm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_certify.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_changeauth.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_cmk.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_context.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_counter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_daa.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_delegate.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_dir.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_ek.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_evlog.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_key.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_maint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_migration.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_nv.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_oper.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_own.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_pcr_extend.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_ps.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_quote.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_quote2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_random.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_seal.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_selftest.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_sign.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_tick.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-rpc_transport.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-spi_utils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-ssl_ui.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-support.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tcs_api.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_admin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_aik.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_asym.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_audit.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_auth.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_bind.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_caps.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_caps_tpm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_certify.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_changeauth.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_context_mem.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_counter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_daa.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_delegate.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_dir.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_ek.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_get_flags.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_key.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_maint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_migration.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_nv.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_oper.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_own.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_pcr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_pcr_extend.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_policy.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_ps.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_quote.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_quote2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_random.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_seal.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_selftest.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_sign.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tsp_tick.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_admin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_aik.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_asn1.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_audit.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_bind.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_caps.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_caps_tpm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_certify.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_changeauth.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_cmk.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_context.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_counter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_daa.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_delegate.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_dir.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_ek.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_getset.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_hash.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_key.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_maint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_migration.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_nv.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_oper.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_own.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_pcr_comp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_pcr_comp12.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_pcr_events.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_pcr_extend.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_policy.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_ps.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_quote.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_quote2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_random.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_seal.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_selftest.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_sign.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_tick.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspi_transport.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-tspps.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-verifier.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtspi_la-verifier_transaction.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +libtspi_la-log.lo: log.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-log.lo -MD -MP -MF $(DEPDIR)/libtspi_la-log.Tpo -c -o libtspi_la-log.lo `test -f 'log.c' || echo '$(srcdir)/'`log.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-log.Tpo $(DEPDIR)/libtspi_la-log.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='log.c' object='libtspi_la-log.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-log.lo `test -f 'log.c' || echo '$(srcdir)/'`log.c + +libtspi_la-spi_utils.lo: spi_utils.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-spi_utils.lo -MD -MP -MF $(DEPDIR)/libtspi_la-spi_utils.Tpo -c -o libtspi_la-spi_utils.lo `test -f 'spi_utils.c' || echo '$(srcdir)/'`spi_utils.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-spi_utils.Tpo $(DEPDIR)/libtspi_la-spi_utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='spi_utils.c' object='libtspi_la-spi_utils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-spi_utils.lo `test -f 'spi_utils.c' || echo '$(srcdir)/'`spi_utils.c + +libtspi_la-obj.lo: obj.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-obj.lo -MD -MP -MF $(DEPDIR)/libtspi_la-obj.Tpo -c -o libtspi_la-obj.lo `test -f 'obj.c' || echo '$(srcdir)/'`obj.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-obj.Tpo $(DEPDIR)/libtspi_la-obj.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='obj.c' object='libtspi_la-obj.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-obj.lo `test -f 'obj.c' || echo '$(srcdir)/'`obj.c + +libtspi_la-obj_policy.lo: obj_policy.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-obj_policy.lo -MD -MP -MF $(DEPDIR)/libtspi_la-obj_policy.Tpo -c -o libtspi_la-obj_policy.lo `test -f 'obj_policy.c' || echo '$(srcdir)/'`obj_policy.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-obj_policy.Tpo $(DEPDIR)/libtspi_la-obj_policy.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='obj_policy.c' object='libtspi_la-obj_policy.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-obj_policy.lo `test -f 'obj_policy.c' || echo '$(srcdir)/'`obj_policy.c + +libtspi_la-tsp_policy.lo: tsp_policy.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_policy.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_policy.Tpo -c -o libtspi_la-tsp_policy.lo `test -f 'tsp_policy.c' || echo '$(srcdir)/'`tsp_policy.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_policy.Tpo $(DEPDIR)/libtspi_la-tsp_policy.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_policy.c' object='libtspi_la-tsp_policy.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_policy.lo `test -f 'tsp_policy.c' || echo '$(srcdir)/'`tsp_policy.c + +libtspi_la-obj_tpm.lo: obj_tpm.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-obj_tpm.lo -MD -MP -MF $(DEPDIR)/libtspi_la-obj_tpm.Tpo -c -o libtspi_la-obj_tpm.lo `test -f 'obj_tpm.c' || echo '$(srcdir)/'`obj_tpm.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-obj_tpm.Tpo $(DEPDIR)/libtspi_la-obj_tpm.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='obj_tpm.c' object='libtspi_la-obj_tpm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-obj_tpm.lo `test -f 'obj_tpm.c' || echo '$(srcdir)/'`obj_tpm.c + +libtspi_la-obj_context.lo: obj_context.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-obj_context.lo -MD -MP -MF $(DEPDIR)/libtspi_la-obj_context.Tpo -c -o libtspi_la-obj_context.lo `test -f 'obj_context.c' || echo '$(srcdir)/'`obj_context.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-obj_context.Tpo $(DEPDIR)/libtspi_la-obj_context.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='obj_context.c' object='libtspi_la-obj_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-obj_context.lo `test -f 'obj_context.c' || echo '$(srcdir)/'`obj_context.c + +libtspi_la-tsp_context_mem.lo: tsp_context_mem.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_context_mem.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_context_mem.Tpo -c -o libtspi_la-tsp_context_mem.lo `test -f 'tsp_context_mem.c' || echo '$(srcdir)/'`tsp_context_mem.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_context_mem.Tpo $(DEPDIR)/libtspi_la-tsp_context_mem.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_context_mem.c' object='libtspi_la-tsp_context_mem.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_context_mem.lo `test -f 'tsp_context_mem.c' || echo '$(srcdir)/'`tsp_context_mem.c + +libtspi_la-tspi_context.lo: tspi_context.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_context.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_context.Tpo -c -o libtspi_la-tspi_context.lo `test -f 'tspi_context.c' || echo '$(srcdir)/'`tspi_context.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_context.Tpo $(DEPDIR)/libtspi_la-tspi_context.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_context.c' object='libtspi_la-tspi_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_context.lo `test -f 'tspi_context.c' || echo '$(srcdir)/'`tspi_context.c + +libtspi_la-rpc_context.lo: rpc/@RPC@/rpc_context.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_context.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_context.Tpo -c -o libtspi_la-rpc_context.lo `test -f 'rpc/@RPC@/rpc_context.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_context.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_context.Tpo $(DEPDIR)/libtspi_la-rpc_context.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_context.c' object='libtspi_la-rpc_context.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_context.lo `test -f 'rpc/@RPC@/rpc_context.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_context.c + +libtspi_la-tcs_api.lo: rpc/tcs_api.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tcs_api.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tcs_api.Tpo -c -o libtspi_la-tcs_api.lo `test -f 'rpc/tcs_api.c' || echo '$(srcdir)/'`rpc/tcs_api.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tcs_api.Tpo $(DEPDIR)/libtspi_la-tcs_api.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/tcs_api.c' object='libtspi_la-tcs_api.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tcs_api.lo `test -f 'rpc/tcs_api.c' || echo '$(srcdir)/'`rpc/tcs_api.c + +libtspi_la-hosttable.lo: rpc/hosttable.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-hosttable.lo -MD -MP -MF $(DEPDIR)/libtspi_la-hosttable.Tpo -c -o libtspi_la-hosttable.lo `test -f 'rpc/hosttable.c' || echo '$(srcdir)/'`rpc/hosttable.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-hosttable.Tpo $(DEPDIR)/libtspi_la-hosttable.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/hosttable.c' object='libtspi_la-hosttable.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-hosttable.lo `test -f 'rpc/hosttable.c' || echo '$(srcdir)/'`rpc/hosttable.c + +libtspi_la-rpc.lo: rpc/@RPC@/rpc.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc.Tpo -c -o libtspi_la-rpc.lo `test -f 'rpc/@RPC@/rpc.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc.Tpo $(DEPDIR)/libtspi_la-rpc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc.c' object='libtspi_la-rpc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc.lo `test -f 'rpc/@RPC@/rpc.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc.c + +libtspi_la-tsp_asym.lo: tsp_asym.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_asym.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_asym.Tpo -c -o libtspi_la-tsp_asym.lo `test -f 'tsp_asym.c' || echo '$(srcdir)/'`tsp_asym.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_asym.Tpo $(DEPDIR)/libtspi_la-tsp_asym.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_asym.c' object='libtspi_la-tsp_asym.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_asym.lo `test -f 'tsp_asym.c' || echo '$(srcdir)/'`tsp_asym.c + +libtspi_la-tspi_oper.lo: tspi_oper.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_oper.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_oper.Tpo -c -o libtspi_la-tspi_oper.lo `test -f 'tspi_oper.c' || echo '$(srcdir)/'`tspi_oper.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_oper.Tpo $(DEPDIR)/libtspi_la-tspi_oper.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_oper.c' object='libtspi_la-tspi_oper.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_oper.lo `test -f 'tspi_oper.c' || echo '$(srcdir)/'`tspi_oper.c + +libtspi_la-tsp_oper.lo: tsp_oper.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_oper.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_oper.Tpo -c -o libtspi_la-tsp_oper.lo `test -f 'tsp_oper.c' || echo '$(srcdir)/'`tsp_oper.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_oper.Tpo $(DEPDIR)/libtspi_la-tsp_oper.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_oper.c' object='libtspi_la-tsp_oper.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_oper.lo `test -f 'tsp_oper.c' || echo '$(srcdir)/'`tsp_oper.c + +libtspi_la-rpc_oper.lo: rpc/@RPC@/rpc_oper.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_oper.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_oper.Tpo -c -o libtspi_la-rpc_oper.lo `test -f 'rpc/@RPC@/rpc_oper.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_oper.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_oper.Tpo $(DEPDIR)/libtspi_la-rpc_oper.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_oper.c' object='libtspi_la-rpc_oper.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_oper.lo `test -f 'rpc/@RPC@/rpc_oper.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_oper.c + +libtspi_la-tspi_transport.lo: tspi_transport.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_transport.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_transport.Tpo -c -o libtspi_la-tspi_transport.lo `test -f 'tspi_transport.c' || echo '$(srcdir)/'`tspi_transport.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_transport.Tpo $(DEPDIR)/libtspi_la-tspi_transport.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_transport.c' object='libtspi_la-tspi_transport.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_transport.lo `test -f 'tspi_transport.c' || echo '$(srcdir)/'`tspi_transport.c + +libtspi_la-rpc_transport.lo: rpc/@RPC@/rpc_transport.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_transport.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_transport.Tpo -c -o libtspi_la-rpc_transport.lo `test -f 'rpc/@RPC@/rpc_transport.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_transport.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_transport.Tpo $(DEPDIR)/libtspi_la-rpc_transport.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_transport.c' object='libtspi_la-rpc_transport.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_transport.lo `test -f 'rpc/@RPC@/rpc_transport.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_transport.c + +libtspi_la-tspi_tick.lo: tspi_tick.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_tick.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_tick.Tpo -c -o libtspi_la-tspi_tick.lo `test -f 'tspi_tick.c' || echo '$(srcdir)/'`tspi_tick.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_tick.Tpo $(DEPDIR)/libtspi_la-tspi_tick.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_tick.c' object='libtspi_la-tspi_tick.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_tick.lo `test -f 'tspi_tick.c' || echo '$(srcdir)/'`tspi_tick.c + +libtspi_la-tsp_tick.lo: tsp_tick.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_tick.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_tick.Tpo -c -o libtspi_la-tsp_tick.lo `test -f 'tsp_tick.c' || echo '$(srcdir)/'`tsp_tick.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_tick.Tpo $(DEPDIR)/libtspi_la-tsp_tick.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_tick.c' object='libtspi_la-tsp_tick.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_tick.lo `test -f 'tsp_tick.c' || echo '$(srcdir)/'`tsp_tick.c + +libtspi_la-rpc_tick.lo: rpc/@RPC@/rpc_tick.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_tick.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_tick.Tpo -c -o libtspi_la-rpc_tick.lo `test -f 'rpc/@RPC@/rpc_tick.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_tick.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_tick.Tpo $(DEPDIR)/libtspi_la-rpc_tick.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_tick.c' object='libtspi_la-rpc_tick.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_tick.lo `test -f 'rpc/@RPC@/rpc_tick.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_tick.c + +libtspi_la-tspi_counter.lo: tspi_counter.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_counter.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_counter.Tpo -c -o libtspi_la-tspi_counter.lo `test -f 'tspi_counter.c' || echo '$(srcdir)/'`tspi_counter.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_counter.Tpo $(DEPDIR)/libtspi_la-tspi_counter.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_counter.c' object='libtspi_la-tspi_counter.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_counter.lo `test -f 'tspi_counter.c' || echo '$(srcdir)/'`tspi_counter.c + +libtspi_la-tsp_counter.lo: tsp_counter.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_counter.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_counter.Tpo -c -o libtspi_la-tsp_counter.lo `test -f 'tsp_counter.c' || echo '$(srcdir)/'`tsp_counter.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_counter.Tpo $(DEPDIR)/libtspi_la-tsp_counter.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_counter.c' object='libtspi_la-tsp_counter.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_counter.lo `test -f 'tsp_counter.c' || echo '$(srcdir)/'`tsp_counter.c + +libtspi_la-rpc_counter.lo: rpc/@RPC@/rpc_counter.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_counter.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_counter.Tpo -c -o libtspi_la-rpc_counter.lo `test -f 'rpc/@RPC@/rpc_counter.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_counter.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_counter.Tpo $(DEPDIR)/libtspi_la-rpc_counter.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_counter.c' object='libtspi_la-rpc_counter.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_counter.lo `test -f 'rpc/@RPC@/rpc_counter.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_counter.c + +libtspi_la-tspi_pcr_comp12.lo: tspi_pcr_comp12.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_pcr_comp12.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_pcr_comp12.Tpo -c -o libtspi_la-tspi_pcr_comp12.lo `test -f 'tspi_pcr_comp12.c' || echo '$(srcdir)/'`tspi_pcr_comp12.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_pcr_comp12.Tpo $(DEPDIR)/libtspi_la-tspi_pcr_comp12.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_pcr_comp12.c' object='libtspi_la-tspi_pcr_comp12.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_pcr_comp12.lo `test -f 'tspi_pcr_comp12.c' || echo '$(srcdir)/'`tspi_pcr_comp12.c + +libtspi_la-tsp_auth.lo: tsp_auth.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_auth.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_auth.Tpo -c -o libtspi_la-tsp_auth.lo `test -f 'tsp_auth.c' || echo '$(srcdir)/'`tsp_auth.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_auth.Tpo $(DEPDIR)/libtspi_la-tsp_auth.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_auth.c' object='libtspi_la-tsp_auth.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_auth.lo `test -f 'tsp_auth.c' || echo '$(srcdir)/'`tsp_auth.c + +libtspi_la-rpc_auth.lo: rpc/@RPC@/rpc_auth.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_auth.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_auth.Tpo -c -o libtspi_la-rpc_auth.lo `test -f 'rpc/@RPC@/rpc_auth.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_auth.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_auth.Tpo $(DEPDIR)/libtspi_la-rpc_auth.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_auth.c' object='libtspi_la-rpc_auth.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_auth.lo `test -f 'rpc/@RPC@/rpc_auth.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_auth.c + +libtspi_la-tspi_getset.lo: tspi_getset.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_getset.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_getset.Tpo -c -o libtspi_la-tspi_getset.lo `test -f 'tspi_getset.c' || echo '$(srcdir)/'`tspi_getset.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_getset.Tpo $(DEPDIR)/libtspi_la-tspi_getset.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_getset.c' object='libtspi_la-tspi_getset.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_getset.lo `test -f 'tspi_getset.c' || echo '$(srcdir)/'`tspi_getset.c + +libtspi_la-tspi_random.lo: tspi_random.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_random.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_random.Tpo -c -o libtspi_la-tspi_random.lo `test -f 'tspi_random.c' || echo '$(srcdir)/'`tspi_random.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_random.Tpo $(DEPDIR)/libtspi_la-tspi_random.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_random.c' object='libtspi_la-tspi_random.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_random.lo `test -f 'tspi_random.c' || echo '$(srcdir)/'`tspi_random.c + +libtspi_la-tsp_random.lo: tsp_random.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_random.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_random.Tpo -c -o libtspi_la-tsp_random.lo `test -f 'tsp_random.c' || echo '$(srcdir)/'`tsp_random.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_random.Tpo $(DEPDIR)/libtspi_la-tsp_random.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_random.c' object='libtspi_la-tsp_random.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_random.lo `test -f 'tsp_random.c' || echo '$(srcdir)/'`tsp_random.c + +libtspi_la-rpc_random.lo: rpc/@RPC@/rpc_random.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_random.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_random.Tpo -c -o libtspi_la-rpc_random.lo `test -f 'rpc/@RPC@/rpc_random.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_random.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_random.Tpo $(DEPDIR)/libtspi_la-rpc_random.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_random.c' object='libtspi_la-rpc_random.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_random.lo `test -f 'rpc/@RPC@/rpc_random.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_random.c + +libtspi_la-tspi_caps.lo: tspi_caps.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_caps.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_caps.Tpo -c -o libtspi_la-tspi_caps.lo `test -f 'tspi_caps.c' || echo '$(srcdir)/'`tspi_caps.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_caps.Tpo $(DEPDIR)/libtspi_la-tspi_caps.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_caps.c' object='libtspi_la-tspi_caps.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_caps.lo `test -f 'tspi_caps.c' || echo '$(srcdir)/'`tspi_caps.c + +libtspi_la-tsp_caps.lo: tsp_caps.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_caps.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_caps.Tpo -c -o libtspi_la-tsp_caps.lo `test -f 'tsp_caps.c' || echo '$(srcdir)/'`tsp_caps.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_caps.Tpo $(DEPDIR)/libtspi_la-tsp_caps.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_caps.c' object='libtspi_la-tsp_caps.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_caps.lo `test -f 'tsp_caps.c' || echo '$(srcdir)/'`tsp_caps.c + +libtspi_la-rpc_caps.lo: rpc/@RPC@/rpc_caps.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_caps.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_caps.Tpo -c -o libtspi_la-rpc_caps.lo `test -f 'rpc/@RPC@/rpc_caps.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_caps.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_caps.Tpo $(DEPDIR)/libtspi_la-rpc_caps.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_caps.c' object='libtspi_la-rpc_caps.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_caps.lo `test -f 'rpc/@RPC@/rpc_caps.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_caps.c + +libtspi_la-tspi_caps_tpm.lo: tspi_caps_tpm.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_caps_tpm.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_caps_tpm.Tpo -c -o libtspi_la-tspi_caps_tpm.lo `test -f 'tspi_caps_tpm.c' || echo '$(srcdir)/'`tspi_caps_tpm.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_caps_tpm.Tpo $(DEPDIR)/libtspi_la-tspi_caps_tpm.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_caps_tpm.c' object='libtspi_la-tspi_caps_tpm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_caps_tpm.lo `test -f 'tspi_caps_tpm.c' || echo '$(srcdir)/'`tspi_caps_tpm.c + +libtspi_la-tsp_caps_tpm.lo: tsp_caps_tpm.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_caps_tpm.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_caps_tpm.Tpo -c -o libtspi_la-tsp_caps_tpm.lo `test -f 'tsp_caps_tpm.c' || echo '$(srcdir)/'`tsp_caps_tpm.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_caps_tpm.Tpo $(DEPDIR)/libtspi_la-tsp_caps_tpm.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_caps_tpm.c' object='libtspi_la-tsp_caps_tpm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_caps_tpm.lo `test -f 'tsp_caps_tpm.c' || echo '$(srcdir)/'`tsp_caps_tpm.c + +libtspi_la-rpc_caps_tpm.lo: rpc/@RPC@/rpc_caps_tpm.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_caps_tpm.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_caps_tpm.Tpo -c -o libtspi_la-rpc_caps_tpm.lo `test -f 'rpc/@RPC@/rpc_caps_tpm.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_caps_tpm.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_caps_tpm.Tpo $(DEPDIR)/libtspi_la-rpc_caps_tpm.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_caps_tpm.c' object='libtspi_la-rpc_caps_tpm.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_caps_tpm.lo `test -f 'rpc/@RPC@/rpc_caps_tpm.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_caps_tpm.c + +libtspi_la-tspi_policy.lo: tspi_policy.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_policy.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_policy.Tpo -c -o libtspi_la-tspi_policy.lo `test -f 'tspi_policy.c' || echo '$(srcdir)/'`tspi_policy.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_policy.Tpo $(DEPDIR)/libtspi_la-tspi_policy.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_policy.c' object='libtspi_la-tspi_policy.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_policy.lo `test -f 'tspi_policy.c' || echo '$(srcdir)/'`tspi_policy.c + +libtspi_la-tspi_dir.lo: tspi_dir.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_dir.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_dir.Tpo -c -o libtspi_la-tspi_dir.lo `test -f 'tspi_dir.c' || echo '$(srcdir)/'`tspi_dir.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_dir.Tpo $(DEPDIR)/libtspi_la-tspi_dir.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_dir.c' object='libtspi_la-tspi_dir.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_dir.lo `test -f 'tspi_dir.c' || echo '$(srcdir)/'`tspi_dir.c + +libtspi_la-tsp_dir.lo: tsp_dir.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_dir.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_dir.Tpo -c -o libtspi_la-tsp_dir.lo `test -f 'tsp_dir.c' || echo '$(srcdir)/'`tsp_dir.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_dir.Tpo $(DEPDIR)/libtspi_la-tsp_dir.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_dir.c' object='libtspi_la-tsp_dir.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_dir.lo `test -f 'tsp_dir.c' || echo '$(srcdir)/'`tsp_dir.c + +libtspi_la-rpc_dir.lo: rpc/@RPC@/rpc_dir.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_dir.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_dir.Tpo -c -o libtspi_la-rpc_dir.lo `test -f 'rpc/@RPC@/rpc_dir.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_dir.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_dir.Tpo $(DEPDIR)/libtspi_la-rpc_dir.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_dir.c' object='libtspi_la-rpc_dir.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_dir.lo `test -f 'rpc/@RPC@/rpc_dir.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_dir.c + +libtspi_la-tspi_pcr_events.lo: tspi_pcr_events.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_pcr_events.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_pcr_events.Tpo -c -o libtspi_la-tspi_pcr_events.lo `test -f 'tspi_pcr_events.c' || echo '$(srcdir)/'`tspi_pcr_events.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_pcr_events.Tpo $(DEPDIR)/libtspi_la-tspi_pcr_events.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_pcr_events.c' object='libtspi_la-tspi_pcr_events.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_pcr_events.lo `test -f 'tspi_pcr_events.c' || echo '$(srcdir)/'`tspi_pcr_events.c + +libtspi_la-rpc_evlog.lo: rpc/@RPC@/rpc_evlog.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_evlog.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_evlog.Tpo -c -o libtspi_la-rpc_evlog.lo `test -f 'rpc/@RPC@/rpc_evlog.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_evlog.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_evlog.Tpo $(DEPDIR)/libtspi_la-rpc_evlog.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_evlog.c' object='libtspi_la-rpc_evlog.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_evlog.lo `test -f 'rpc/@RPC@/rpc_evlog.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_evlog.c + +libtspi_la-tspi_hash.lo: tspi_hash.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_hash.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_hash.Tpo -c -o libtspi_la-tspi_hash.lo `test -f 'tspi_hash.c' || echo '$(srcdir)/'`tspi_hash.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_hash.Tpo $(DEPDIR)/libtspi_la-tspi_hash.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_hash.c' object='libtspi_la-tspi_hash.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_hash.lo `test -f 'tspi_hash.c' || echo '$(srcdir)/'`tspi_hash.c + +libtspi_la-tspi_sign.lo: tspi_sign.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_sign.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_sign.Tpo -c -o libtspi_la-tspi_sign.lo `test -f 'tspi_sign.c' || echo '$(srcdir)/'`tspi_sign.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_sign.Tpo $(DEPDIR)/libtspi_la-tspi_sign.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_sign.c' object='libtspi_la-tspi_sign.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_sign.lo `test -f 'tspi_sign.c' || echo '$(srcdir)/'`tspi_sign.c + +libtspi_la-tsp_sign.lo: tsp_sign.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_sign.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_sign.Tpo -c -o libtspi_la-tsp_sign.lo `test -f 'tsp_sign.c' || echo '$(srcdir)/'`tsp_sign.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_sign.Tpo $(DEPDIR)/libtspi_la-tsp_sign.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_sign.c' object='libtspi_la-tsp_sign.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_sign.lo `test -f 'tsp_sign.c' || echo '$(srcdir)/'`tsp_sign.c + +libtspi_la-rpc_sign.lo: rpc/@RPC@/rpc_sign.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_sign.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_sign.Tpo -c -o libtspi_la-rpc_sign.lo `test -f 'rpc/@RPC@/rpc_sign.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_sign.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_sign.Tpo $(DEPDIR)/libtspi_la-rpc_sign.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_sign.c' object='libtspi_la-rpc_sign.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_sign.lo `test -f 'rpc/@RPC@/rpc_sign.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_sign.c + +libtspi_la-tspi_quote.lo: tspi_quote.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_quote.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_quote.Tpo -c -o libtspi_la-tspi_quote.lo `test -f 'tspi_quote.c' || echo '$(srcdir)/'`tspi_quote.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_quote.Tpo $(DEPDIR)/libtspi_la-tspi_quote.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_quote.c' object='libtspi_la-tspi_quote.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_quote.lo `test -f 'tspi_quote.c' || echo '$(srcdir)/'`tspi_quote.c + +libtspi_la-tsp_quote.lo: tsp_quote.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_quote.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_quote.Tpo -c -o libtspi_la-tsp_quote.lo `test -f 'tsp_quote.c' || echo '$(srcdir)/'`tsp_quote.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_quote.Tpo $(DEPDIR)/libtspi_la-tsp_quote.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_quote.c' object='libtspi_la-tsp_quote.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_quote.lo `test -f 'tsp_quote.c' || echo '$(srcdir)/'`tsp_quote.c + +libtspi_la-rpc_quote.lo: rpc/@RPC@/rpc_quote.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_quote.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_quote.Tpo -c -o libtspi_la-rpc_quote.lo `test -f 'rpc/@RPC@/rpc_quote.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_quote.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_quote.Tpo $(DEPDIR)/libtspi_la-rpc_quote.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_quote.c' object='libtspi_la-rpc_quote.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_quote.lo `test -f 'rpc/@RPC@/rpc_quote.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_quote.c + +libtspi_la-tspi_pcr_comp.lo: tspi_pcr_comp.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_pcr_comp.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_pcr_comp.Tpo -c -o libtspi_la-tspi_pcr_comp.lo `test -f 'tspi_pcr_comp.c' || echo '$(srcdir)/'`tspi_pcr_comp.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_pcr_comp.Tpo $(DEPDIR)/libtspi_la-tspi_pcr_comp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_pcr_comp.c' object='libtspi_la-tspi_pcr_comp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_pcr_comp.lo `test -f 'tspi_pcr_comp.c' || echo '$(srcdir)/'`tspi_pcr_comp.c + +libtspi_la-tspi_seal.lo: tspi_seal.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_seal.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_seal.Tpo -c -o libtspi_la-tspi_seal.lo `test -f 'tspi_seal.c' || echo '$(srcdir)/'`tspi_seal.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_seal.Tpo $(DEPDIR)/libtspi_la-tspi_seal.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_seal.c' object='libtspi_la-tspi_seal.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_seal.lo `test -f 'tspi_seal.c' || echo '$(srcdir)/'`tspi_seal.c + +libtspi_la-rpc_seal.lo: rpc/@RPC@/rpc_seal.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_seal.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_seal.Tpo -c -o libtspi_la-rpc_seal.lo `test -f 'rpc/@RPC@/rpc_seal.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_seal.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_seal.Tpo $(DEPDIR)/libtspi_la-rpc_seal.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_seal.c' object='libtspi_la-rpc_seal.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_seal.lo `test -f 'rpc/@RPC@/rpc_seal.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_seal.c + +libtspi_la-tspi_changeauth.lo: tspi_changeauth.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_changeauth.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_changeauth.Tpo -c -o libtspi_la-tspi_changeauth.lo `test -f 'tspi_changeauth.c' || echo '$(srcdir)/'`tspi_changeauth.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_changeauth.Tpo $(DEPDIR)/libtspi_la-tspi_changeauth.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_changeauth.c' object='libtspi_la-tspi_changeauth.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_changeauth.lo `test -f 'tspi_changeauth.c' || echo '$(srcdir)/'`tspi_changeauth.c + +libtspi_la-tsp_changeauth.lo: tsp_changeauth.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_changeauth.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_changeauth.Tpo -c -o libtspi_la-tsp_changeauth.lo `test -f 'tsp_changeauth.c' || echo '$(srcdir)/'`tsp_changeauth.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_changeauth.Tpo $(DEPDIR)/libtspi_la-tsp_changeauth.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_changeauth.c' object='libtspi_la-tsp_changeauth.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_changeauth.lo `test -f 'tsp_changeauth.c' || echo '$(srcdir)/'`tsp_changeauth.c + +libtspi_la-rpc_changeauth.lo: rpc/@RPC@/rpc_changeauth.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_changeauth.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_changeauth.Tpo -c -o libtspi_la-rpc_changeauth.lo `test -f 'rpc/@RPC@/rpc_changeauth.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_changeauth.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_changeauth.Tpo $(DEPDIR)/libtspi_la-rpc_changeauth.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_changeauth.c' object='libtspi_la-rpc_changeauth.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_changeauth.lo `test -f 'rpc/@RPC@/rpc_changeauth.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_changeauth.c + +libtspi_la-tspi_bind.lo: tspi_bind.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_bind.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_bind.Tpo -c -o libtspi_la-tspi_bind.lo `test -f 'tspi_bind.c' || echo '$(srcdir)/'`tspi_bind.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_bind.Tpo $(DEPDIR)/libtspi_la-tspi_bind.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_bind.c' object='libtspi_la-tspi_bind.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_bind.lo `test -f 'tspi_bind.c' || echo '$(srcdir)/'`tspi_bind.c + +libtspi_la-tsp_bind.lo: tsp_bind.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_bind.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_bind.Tpo -c -o libtspi_la-tsp_bind.lo `test -f 'tsp_bind.c' || echo '$(srcdir)/'`tsp_bind.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_bind.Tpo $(DEPDIR)/libtspi_la-tsp_bind.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_bind.c' object='libtspi_la-tsp_bind.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_bind.lo `test -f 'tsp_bind.c' || echo '$(srcdir)/'`tsp_bind.c + +libtspi_la-rpc_bind.lo: rpc/@RPC@/rpc_bind.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_bind.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_bind.Tpo -c -o libtspi_la-rpc_bind.lo `test -f 'rpc/@RPC@/rpc_bind.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_bind.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_bind.Tpo $(DEPDIR)/libtspi_la-rpc_bind.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_bind.c' object='libtspi_la-rpc_bind.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_bind.lo `test -f 'rpc/@RPC@/rpc_bind.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_bind.c + +libtspi_la-tsp_own.lo: tsp_own.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_own.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_own.Tpo -c -o libtspi_la-tsp_own.lo `test -f 'tsp_own.c' || echo '$(srcdir)/'`tsp_own.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_own.Tpo $(DEPDIR)/libtspi_la-tsp_own.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_own.c' object='libtspi_la-tsp_own.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_own.lo `test -f 'tsp_own.c' || echo '$(srcdir)/'`tsp_own.c + +libtspi_la-tspi_own.lo: tspi_own.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_own.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_own.Tpo -c -o libtspi_la-tspi_own.lo `test -f 'tspi_own.c' || echo '$(srcdir)/'`tspi_own.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_own.Tpo $(DEPDIR)/libtspi_la-tspi_own.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_own.c' object='libtspi_la-tspi_own.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_own.lo `test -f 'tspi_own.c' || echo '$(srcdir)/'`tspi_own.c + +libtspi_la-rpc_own.lo: rpc/@RPC@/rpc_own.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_own.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_own.Tpo -c -o libtspi_la-rpc_own.lo `test -f 'rpc/@RPC@/rpc_own.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_own.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_own.Tpo $(DEPDIR)/libtspi_la-rpc_own.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_own.c' object='libtspi_la-rpc_own.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_own.lo `test -f 'rpc/@RPC@/rpc_own.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_own.c + +libtspi_la-ps_utils.lo: ps/ps_utils.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-ps_utils.lo -MD -MP -MF $(DEPDIR)/libtspi_la-ps_utils.Tpo -c -o libtspi_la-ps_utils.lo `test -f 'ps/ps_utils.c' || echo '$(srcdir)/'`ps/ps_utils.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-ps_utils.Tpo $(DEPDIR)/libtspi_la-ps_utils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ps/ps_utils.c' object='libtspi_la-ps_utils.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-ps_utils.lo `test -f 'ps/ps_utils.c' || echo '$(srcdir)/'`ps/ps_utils.c + +libtspi_la-tspps.lo: ps/tspps.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspps.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspps.Tpo -c -o libtspi_la-tspps.lo `test -f 'ps/tspps.c' || echo '$(srcdir)/'`ps/tspps.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspps.Tpo $(DEPDIR)/libtspi_la-tspps.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ps/tspps.c' object='libtspi_la-tspps.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspps.lo `test -f 'ps/tspps.c' || echo '$(srcdir)/'`ps/tspps.c + +libtspi_la-tspi_ps.lo: tspi_ps.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_ps.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_ps.Tpo -c -o libtspi_la-tspi_ps.lo `test -f 'tspi_ps.c' || echo '$(srcdir)/'`tspi_ps.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_ps.Tpo $(DEPDIR)/libtspi_la-tspi_ps.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_ps.c' object='libtspi_la-tspi_ps.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_ps.lo `test -f 'tspi_ps.c' || echo '$(srcdir)/'`tspi_ps.c + +libtspi_la-rpc_ps.lo: rpc/@RPC@/rpc_ps.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_ps.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_ps.Tpo -c -o libtspi_la-rpc_ps.lo `test -f 'rpc/@RPC@/rpc_ps.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_ps.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_ps.Tpo $(DEPDIR)/libtspi_la-rpc_ps.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_ps.c' object='libtspi_la-rpc_ps.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_ps.lo `test -f 'rpc/@RPC@/rpc_ps.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_ps.c + +libtspi_la-tsp_ps.lo: tsp_ps.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_ps.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_ps.Tpo -c -o libtspi_la-tsp_ps.lo `test -f 'tsp_ps.c' || echo '$(srcdir)/'`tsp_ps.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_ps.Tpo $(DEPDIR)/libtspi_la-tsp_ps.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_ps.c' object='libtspi_la-tsp_ps.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_ps.lo `test -f 'tsp_ps.c' || echo '$(srcdir)/'`tsp_ps.c + +libtspi_la-tspi_admin.lo: tspi_admin.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_admin.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_admin.Tpo -c -o libtspi_la-tspi_admin.lo `test -f 'tspi_admin.c' || echo '$(srcdir)/'`tspi_admin.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_admin.Tpo $(DEPDIR)/libtspi_la-tspi_admin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_admin.c' object='libtspi_la-tspi_admin.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_admin.lo `test -f 'tspi_admin.c' || echo '$(srcdir)/'`tspi_admin.c + +libtspi_la-tsp_admin.lo: tsp_admin.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_admin.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_admin.Tpo -c -o libtspi_la-tsp_admin.lo `test -f 'tsp_admin.c' || echo '$(srcdir)/'`tsp_admin.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_admin.Tpo $(DEPDIR)/libtspi_la-tsp_admin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_admin.c' object='libtspi_la-tsp_admin.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_admin.lo `test -f 'tsp_admin.c' || echo '$(srcdir)/'`tsp_admin.c + +libtspi_la-rpc_admin.lo: rpc/@RPC@/rpc_admin.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_admin.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_admin.Tpo -c -o libtspi_la-rpc_admin.lo `test -f 'rpc/@RPC@/rpc_admin.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_admin.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_admin.Tpo $(DEPDIR)/libtspi_la-rpc_admin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_admin.c' object='libtspi_la-rpc_admin.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_admin.lo `test -f 'rpc/@RPC@/rpc_admin.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_admin.c + +libtspi_la-tspi_aik.lo: tspi_aik.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_aik.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_aik.Tpo -c -o libtspi_la-tspi_aik.lo `test -f 'tspi_aik.c' || echo '$(srcdir)/'`tspi_aik.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_aik.Tpo $(DEPDIR)/libtspi_la-tspi_aik.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_aik.c' object='libtspi_la-tspi_aik.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_aik.lo `test -f 'tspi_aik.c' || echo '$(srcdir)/'`tspi_aik.c + +libtspi_la-tsp_aik.lo: tsp_aik.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_aik.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_aik.Tpo -c -o libtspi_la-tsp_aik.lo `test -f 'tsp_aik.c' || echo '$(srcdir)/'`tsp_aik.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_aik.Tpo $(DEPDIR)/libtspi_la-tsp_aik.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_aik.c' object='libtspi_la-tsp_aik.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_aik.lo `test -f 'tsp_aik.c' || echo '$(srcdir)/'`tsp_aik.c + +libtspi_la-rpc_aik.lo: rpc/@RPC@/rpc_aik.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_aik.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_aik.Tpo -c -o libtspi_la-rpc_aik.lo `test -f 'rpc/@RPC@/rpc_aik.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_aik.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_aik.Tpo $(DEPDIR)/libtspi_la-rpc_aik.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_aik.c' object='libtspi_la-rpc_aik.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_aik.lo `test -f 'rpc/@RPC@/rpc_aik.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_aik.c + +libtspi_la-tspi_ek.lo: tspi_ek.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_ek.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_ek.Tpo -c -o libtspi_la-tspi_ek.lo `test -f 'tspi_ek.c' || echo '$(srcdir)/'`tspi_ek.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_ek.Tpo $(DEPDIR)/libtspi_la-tspi_ek.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_ek.c' object='libtspi_la-tspi_ek.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_ek.lo `test -f 'tspi_ek.c' || echo '$(srcdir)/'`tspi_ek.c + +libtspi_la-tsp_ek.lo: tsp_ek.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_ek.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_ek.Tpo -c -o libtspi_la-tsp_ek.lo `test -f 'tsp_ek.c' || echo '$(srcdir)/'`tsp_ek.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_ek.Tpo $(DEPDIR)/libtspi_la-tsp_ek.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_ek.c' object='libtspi_la-tsp_ek.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_ek.lo `test -f 'tsp_ek.c' || echo '$(srcdir)/'`tsp_ek.c + +libtspi_la-rpc_ek.lo: rpc/@RPC@/rpc_ek.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_ek.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_ek.Tpo -c -o libtspi_la-rpc_ek.lo `test -f 'rpc/@RPC@/rpc_ek.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_ek.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_ek.Tpo $(DEPDIR)/libtspi_la-rpc_ek.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_ek.c' object='libtspi_la-rpc_ek.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_ek.lo `test -f 'rpc/@RPC@/rpc_ek.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_ek.c + +libtspi_la-tspi_certify.lo: tspi_certify.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_certify.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_certify.Tpo -c -o libtspi_la-tspi_certify.lo `test -f 'tspi_certify.c' || echo '$(srcdir)/'`tspi_certify.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_certify.Tpo $(DEPDIR)/libtspi_la-tspi_certify.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_certify.c' object='libtspi_la-tspi_certify.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_certify.lo `test -f 'tspi_certify.c' || echo '$(srcdir)/'`tspi_certify.c + +libtspi_la-tsp_certify.lo: tsp_certify.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_certify.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_certify.Tpo -c -o libtspi_la-tsp_certify.lo `test -f 'tsp_certify.c' || echo '$(srcdir)/'`tsp_certify.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_certify.Tpo $(DEPDIR)/libtspi_la-tsp_certify.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_certify.c' object='libtspi_la-tsp_certify.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_certify.lo `test -f 'tsp_certify.c' || echo '$(srcdir)/'`tsp_certify.c + +libtspi_la-rpc_certify.lo: rpc/@RPC@/rpc_certify.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_certify.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_certify.Tpo -c -o libtspi_la-rpc_certify.lo `test -f 'rpc/@RPC@/rpc_certify.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_certify.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_certify.Tpo $(DEPDIR)/libtspi_la-rpc_certify.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_certify.c' object='libtspi_la-rpc_certify.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_certify.lo `test -f 'rpc/@RPC@/rpc_certify.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_certify.c + +libtspi_la-tspi_key.lo: tspi_key.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_key.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_key.Tpo -c -o libtspi_la-tspi_key.lo `test -f 'tspi_key.c' || echo '$(srcdir)/'`tspi_key.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_key.Tpo $(DEPDIR)/libtspi_la-tspi_key.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_key.c' object='libtspi_la-tspi_key.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_key.lo `test -f 'tspi_key.c' || echo '$(srcdir)/'`tspi_key.c + +libtspi_la-rpc_key.lo: rpc/@RPC@/rpc_key.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_key.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_key.Tpo -c -o libtspi_la-rpc_key.lo `test -f 'rpc/@RPC@/rpc_key.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_key.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_key.Tpo $(DEPDIR)/libtspi_la-rpc_key.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_key.c' object='libtspi_la-rpc_key.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_key.lo `test -f 'rpc/@RPC@/rpc_key.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_key.c + +libtspi_la-tspi_maint.lo: tspi_maint.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_maint.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_maint.Tpo -c -o libtspi_la-tspi_maint.lo `test -f 'tspi_maint.c' || echo '$(srcdir)/'`tspi_maint.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_maint.Tpo $(DEPDIR)/libtspi_la-tspi_maint.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_maint.c' object='libtspi_la-tspi_maint.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_maint.lo `test -f 'tspi_maint.c' || echo '$(srcdir)/'`tspi_maint.c + +libtspi_la-tsp_maint.lo: tsp_maint.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_maint.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_maint.Tpo -c -o libtspi_la-tsp_maint.lo `test -f 'tsp_maint.c' || echo '$(srcdir)/'`tsp_maint.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_maint.Tpo $(DEPDIR)/libtspi_la-tsp_maint.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_maint.c' object='libtspi_la-tsp_maint.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_maint.lo `test -f 'tsp_maint.c' || echo '$(srcdir)/'`tsp_maint.c + +libtspi_la-rpc_maint.lo: rpc/@RPC@/rpc_maint.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_maint.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_maint.Tpo -c -o libtspi_la-rpc_maint.lo `test -f 'rpc/@RPC@/rpc_maint.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_maint.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_maint.Tpo $(DEPDIR)/libtspi_la-rpc_maint.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_maint.c' object='libtspi_la-rpc_maint.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_maint.lo `test -f 'rpc/@RPC@/rpc_maint.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_maint.c + +libtspi_la-tspi_migration.lo: tspi_migration.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_migration.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_migration.Tpo -c -o libtspi_la-tspi_migration.lo `test -f 'tspi_migration.c' || echo '$(srcdir)/'`tspi_migration.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_migration.Tpo $(DEPDIR)/libtspi_la-tspi_migration.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_migration.c' object='libtspi_la-tspi_migration.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_migration.lo `test -f 'tspi_migration.c' || echo '$(srcdir)/'`tspi_migration.c + +libtspi_la-tsp_migration.lo: tsp_migration.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_migration.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_migration.Tpo -c -o libtspi_la-tsp_migration.lo `test -f 'tsp_migration.c' || echo '$(srcdir)/'`tsp_migration.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_migration.Tpo $(DEPDIR)/libtspi_la-tsp_migration.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_migration.c' object='libtspi_la-tsp_migration.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_migration.lo `test -f 'tsp_migration.c' || echo '$(srcdir)/'`tsp_migration.c + +libtspi_la-rpc_migration.lo: rpc/@RPC@/rpc_migration.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_migration.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_migration.Tpo -c -o libtspi_la-rpc_migration.lo `test -f 'rpc/@RPC@/rpc_migration.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_migration.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_migration.Tpo $(DEPDIR)/libtspi_la-rpc_migration.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_migration.c' object='libtspi_la-rpc_migration.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_migration.lo `test -f 'rpc/@RPC@/rpc_migration.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_migration.c + +libtspi_la-tspi_pcr_extend.lo: tspi_pcr_extend.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_pcr_extend.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_pcr_extend.Tpo -c -o libtspi_la-tspi_pcr_extend.lo `test -f 'tspi_pcr_extend.c' || echo '$(srcdir)/'`tspi_pcr_extend.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_pcr_extend.Tpo $(DEPDIR)/libtspi_la-tspi_pcr_extend.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_pcr_extend.c' object='libtspi_la-tspi_pcr_extend.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_pcr_extend.lo `test -f 'tspi_pcr_extend.c' || echo '$(srcdir)/'`tspi_pcr_extend.c + +libtspi_la-tsp_pcr_extend.lo: tsp_pcr_extend.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_pcr_extend.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_pcr_extend.Tpo -c -o libtspi_la-tsp_pcr_extend.lo `test -f 'tsp_pcr_extend.c' || echo '$(srcdir)/'`tsp_pcr_extend.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_pcr_extend.Tpo $(DEPDIR)/libtspi_la-tsp_pcr_extend.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_pcr_extend.c' object='libtspi_la-tsp_pcr_extend.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_pcr_extend.lo `test -f 'tsp_pcr_extend.c' || echo '$(srcdir)/'`tsp_pcr_extend.c + +libtspi_la-rpc_pcr_extend.lo: rpc/@RPC@/rpc_pcr_extend.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_pcr_extend.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_pcr_extend.Tpo -c -o libtspi_la-rpc_pcr_extend.lo `test -f 'rpc/@RPC@/rpc_pcr_extend.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_pcr_extend.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_pcr_extend.Tpo $(DEPDIR)/libtspi_la-rpc_pcr_extend.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_pcr_extend.c' object='libtspi_la-rpc_pcr_extend.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_pcr_extend.lo `test -f 'rpc/@RPC@/rpc_pcr_extend.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_pcr_extend.c + +libtspi_la-tspi_selftest.lo: tspi_selftest.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_selftest.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_selftest.Tpo -c -o libtspi_la-tspi_selftest.lo `test -f 'tspi_selftest.c' || echo '$(srcdir)/'`tspi_selftest.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_selftest.Tpo $(DEPDIR)/libtspi_la-tspi_selftest.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_selftest.c' object='libtspi_la-tspi_selftest.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_selftest.lo `test -f 'tspi_selftest.c' || echo '$(srcdir)/'`tspi_selftest.c + +libtspi_la-tsp_selftest.lo: tsp_selftest.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_selftest.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_selftest.Tpo -c -o libtspi_la-tsp_selftest.lo `test -f 'tsp_selftest.c' || echo '$(srcdir)/'`tsp_selftest.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_selftest.Tpo $(DEPDIR)/libtspi_la-tsp_selftest.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_selftest.c' object='libtspi_la-tsp_selftest.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_selftest.lo `test -f 'tsp_selftest.c' || echo '$(srcdir)/'`tsp_selftest.c + +libtspi_la-rpc_selftest.lo: rpc/@RPC@/rpc_selftest.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_selftest.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_selftest.Tpo -c -o libtspi_la-rpc_selftest.lo `test -f 'rpc/@RPC@/rpc_selftest.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_selftest.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_selftest.Tpo $(DEPDIR)/libtspi_la-rpc_selftest.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_selftest.c' object='libtspi_la-rpc_selftest.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_selftest.lo `test -f 'rpc/@RPC@/rpc_selftest.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_selftest.c + +libtspi_la-tspi_daa.lo: tspi_daa.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_daa.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_daa.Tpo -c -o libtspi_la-tspi_daa.lo `test -f 'tspi_daa.c' || echo '$(srcdir)/'`tspi_daa.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_daa.Tpo $(DEPDIR)/libtspi_la-tspi_daa.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_daa.c' object='libtspi_la-tspi_daa.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_daa.lo `test -f 'tspi_daa.c' || echo '$(srcdir)/'`tspi_daa.c + +libtspi_la-tsp_daa.lo: tsp_daa.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_daa.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_daa.Tpo -c -o libtspi_la-tsp_daa.lo `test -f 'tsp_daa.c' || echo '$(srcdir)/'`tsp_daa.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_daa.Tpo $(DEPDIR)/libtspi_la-tsp_daa.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_daa.c' object='libtspi_la-tsp_daa.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_daa.lo `test -f 'tsp_daa.c' || echo '$(srcdir)/'`tsp_daa.c + +libtspi_la-rpc_daa.lo: rpc/@RPC@/rpc_daa.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_daa.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_daa.Tpo -c -o libtspi_la-rpc_daa.lo `test -f 'rpc/@RPC@/rpc_daa.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_daa.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_daa.Tpo $(DEPDIR)/libtspi_la-rpc_daa.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_daa.c' object='libtspi_la-rpc_daa.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_daa.lo `test -f 'rpc/@RPC@/rpc_daa.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_daa.c + +libtspi_la-keypair_generator.lo: daa/daa_issuer/keypair_generator.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-keypair_generator.lo -MD -MP -MF $(DEPDIR)/libtspi_la-keypair_generator.Tpo -c -o libtspi_la-keypair_generator.lo `test -f 'daa/daa_issuer/keypair_generator.c' || echo '$(srcdir)/'`daa/daa_issuer/keypair_generator.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-keypair_generator.Tpo $(DEPDIR)/libtspi_la-keypair_generator.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='daa/daa_issuer/keypair_generator.c' object='libtspi_la-keypair_generator.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-keypair_generator.lo `test -f 'daa/daa_issuer/keypair_generator.c' || echo '$(srcdir)/'`daa/daa_issuer/keypair_generator.c + +libtspi_la-prime_gen.lo: daa/daa_issuer/prime_gen.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-prime_gen.lo -MD -MP -MF $(DEPDIR)/libtspi_la-prime_gen.Tpo -c -o libtspi_la-prime_gen.lo `test -f 'daa/daa_issuer/prime_gen.c' || echo '$(srcdir)/'`daa/daa_issuer/prime_gen.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-prime_gen.Tpo $(DEPDIR)/libtspi_la-prime_gen.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='daa/daa_issuer/prime_gen.c' object='libtspi_la-prime_gen.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-prime_gen.lo `test -f 'daa/daa_issuer/prime_gen.c' || echo '$(srcdir)/'`daa/daa_issuer/prime_gen.c + +libtspi_la-key_correctness_proof.lo: daa/daa_issuer/key_correctness_proof.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-key_correctness_proof.lo -MD -MP -MF $(DEPDIR)/libtspi_la-key_correctness_proof.Tpo -c -o libtspi_la-key_correctness_proof.lo `test -f 'daa/daa_issuer/key_correctness_proof.c' || echo '$(srcdir)/'`daa/daa_issuer/key_correctness_proof.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-key_correctness_proof.Tpo $(DEPDIR)/libtspi_la-key_correctness_proof.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='daa/daa_issuer/key_correctness_proof.c' object='libtspi_la-key_correctness_proof.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-key_correctness_proof.lo `test -f 'daa/daa_issuer/key_correctness_proof.c' || echo '$(srcdir)/'`daa/daa_issuer/key_correctness_proof.c + +libtspi_la-platform.lo: daa/daa_platform/platform.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-platform.lo -MD -MP -MF $(DEPDIR)/libtspi_la-platform.Tpo -c -o libtspi_la-platform.lo `test -f 'daa/daa_platform/platform.c' || echo '$(srcdir)/'`daa/daa_platform/platform.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-platform.Tpo $(DEPDIR)/libtspi_la-platform.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='daa/daa_platform/platform.c' object='libtspi_la-platform.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-platform.lo `test -f 'daa/daa_platform/platform.c' || echo '$(srcdir)/'`daa/daa_platform/platform.c + +libtspi_la-issuer_init.lo: daa/daa_issuer/issuer_init.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-issuer_init.lo -MD -MP -MF $(DEPDIR)/libtspi_la-issuer_init.Tpo -c -o libtspi_la-issuer_init.lo `test -f 'daa/daa_issuer/issuer_init.c' || echo '$(srcdir)/'`daa/daa_issuer/issuer_init.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-issuer_init.Tpo $(DEPDIR)/libtspi_la-issuer_init.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='daa/daa_issuer/issuer_init.c' object='libtspi_la-issuer_init.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-issuer_init.lo `test -f 'daa/daa_issuer/issuer_init.c' || echo '$(srcdir)/'`daa/daa_issuer/issuer_init.c + +libtspi_la-issue_credential.lo: daa/daa_issuer/issue_credential.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-issue_credential.lo -MD -MP -MF $(DEPDIR)/libtspi_la-issue_credential.Tpo -c -o libtspi_la-issue_credential.lo `test -f 'daa/daa_issuer/issue_credential.c' || echo '$(srcdir)/'`daa/daa_issuer/issue_credential.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-issue_credential.Tpo $(DEPDIR)/libtspi_la-issue_credential.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='daa/daa_issuer/issue_credential.c' object='libtspi_la-issue_credential.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-issue_credential.lo `test -f 'daa/daa_issuer/issue_credential.c' || echo '$(srcdir)/'`daa/daa_issuer/issue_credential.c + +libtspi_la-verifier_transaction.lo: daa/daa_verifier/verifier_transaction.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-verifier_transaction.lo -MD -MP -MF $(DEPDIR)/libtspi_la-verifier_transaction.Tpo -c -o libtspi_la-verifier_transaction.lo `test -f 'daa/daa_verifier/verifier_transaction.c' || echo '$(srcdir)/'`daa/daa_verifier/verifier_transaction.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-verifier_transaction.Tpo $(DEPDIR)/libtspi_la-verifier_transaction.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='daa/daa_verifier/verifier_transaction.c' object='libtspi_la-verifier_transaction.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-verifier_transaction.lo `test -f 'daa/daa_verifier/verifier_transaction.c' || echo '$(srcdir)/'`daa/daa_verifier/verifier_transaction.c + +libtspi_la-verifier.lo: daa/daa_verifier/verifier.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-verifier.lo -MD -MP -MF $(DEPDIR)/libtspi_la-verifier.Tpo -c -o libtspi_la-verifier.lo `test -f 'daa/daa_verifier/verifier.c' || echo '$(srcdir)/'`daa/daa_verifier/verifier.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-verifier.Tpo $(DEPDIR)/libtspi_la-verifier.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='daa/daa_verifier/verifier.c' object='libtspi_la-verifier.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-verifier.lo `test -f 'daa/daa_verifier/verifier.c' || echo '$(srcdir)/'`daa/daa_verifier/verifier.c + +libtspi_la-daa_structs.lo: daa/daa_structs.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-daa_structs.lo -MD -MP -MF $(DEPDIR)/libtspi_la-daa_structs.Tpo -c -o libtspi_la-daa_structs.lo `test -f 'daa/daa_structs.c' || echo '$(srcdir)/'`daa/daa_structs.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-daa_structs.Tpo $(DEPDIR)/libtspi_la-daa_structs.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='daa/daa_structs.c' object='libtspi_la-daa_structs.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-daa_structs.lo `test -f 'daa/daa_structs.c' || echo '$(srcdir)/'`daa/daa_structs.c + +libtspi_la-daa_parameter.lo: daa/daa_parameter.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-daa_parameter.lo -MD -MP -MF $(DEPDIR)/libtspi_la-daa_parameter.Tpo -c -o libtspi_la-daa_parameter.lo `test -f 'daa/daa_parameter.c' || echo '$(srcdir)/'`daa/daa_parameter.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-daa_parameter.Tpo $(DEPDIR)/libtspi_la-daa_parameter.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='daa/daa_parameter.c' object='libtspi_la-daa_parameter.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-daa_parameter.lo `test -f 'daa/daa_parameter.c' || echo '$(srcdir)/'`daa/daa_parameter.c + +libtspi_la-bi_gmp.lo: daa/big_integer/bi_gmp.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-bi_gmp.lo -MD -MP -MF $(DEPDIR)/libtspi_la-bi_gmp.Tpo -c -o libtspi_la-bi_gmp.lo `test -f 'daa/big_integer/bi_gmp.c' || echo '$(srcdir)/'`daa/big_integer/bi_gmp.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-bi_gmp.Tpo $(DEPDIR)/libtspi_la-bi_gmp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='daa/big_integer/bi_gmp.c' object='libtspi_la-bi_gmp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-bi_gmp.lo `test -f 'daa/big_integer/bi_gmp.c' || echo '$(srcdir)/'`daa/big_integer/bi_gmp.c + +libtspi_la-bi_openssl.lo: daa/big_integer/bi_openssl.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-bi_openssl.lo -MD -MP -MF $(DEPDIR)/libtspi_la-bi_openssl.Tpo -c -o libtspi_la-bi_openssl.lo `test -f 'daa/big_integer/bi_openssl.c' || echo '$(srcdir)/'`daa/big_integer/bi_openssl.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-bi_openssl.Tpo $(DEPDIR)/libtspi_la-bi_openssl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='daa/big_integer/bi_openssl.c' object='libtspi_la-bi_openssl.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-bi_openssl.lo `test -f 'daa/big_integer/bi_openssl.c' || echo '$(srcdir)/'`daa/big_integer/bi_openssl.c + +libtspi_la-csencryption_result.lo: daa/daa_anonymityrevocation/csencryption_result.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-csencryption_result.lo -MD -MP -MF $(DEPDIR)/libtspi_la-csencryption_result.Tpo -c -o libtspi_la-csencryption_result.lo `test -f 'daa/daa_anonymityrevocation/csencryption_result.c' || echo '$(srcdir)/'`daa/daa_anonymityrevocation/csencryption_result.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-csencryption_result.Tpo $(DEPDIR)/libtspi_la-csencryption_result.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='daa/daa_anonymityrevocation/csencryption_result.c' object='libtspi_la-csencryption_result.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-csencryption_result.lo `test -f 'daa/daa_anonymityrevocation/csencryption_result.c' || echo '$(srcdir)/'`daa/daa_anonymityrevocation/csencryption_result.c + +libtspi_la-bi.lo: daa/big_integer/bi.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-bi.lo -MD -MP -MF $(DEPDIR)/libtspi_la-bi.Tpo -c -o libtspi_la-bi.lo `test -f 'daa/big_integer/bi.c' || echo '$(srcdir)/'`daa/big_integer/bi.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-bi.Tpo $(DEPDIR)/libtspi_la-bi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='daa/big_integer/bi.c' object='libtspi_la-bi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-bi.lo `test -f 'daa/big_integer/bi.c' || echo '$(srcdir)/'`daa/big_integer/bi.c + +libtspi_la-list.lo: daa/utils/list.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-list.lo -MD -MP -MF $(DEPDIR)/libtspi_la-list.Tpo -c -o libtspi_la-list.lo `test -f 'daa/utils/list.c' || echo '$(srcdir)/'`daa/utils/list.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-list.Tpo $(DEPDIR)/libtspi_la-list.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='daa/utils/list.c' object='libtspi_la-list.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-list.lo `test -f 'daa/utils/list.c' || echo '$(srcdir)/'`daa/utils/list.c + +libtspi_la-tsp_get_flags.lo: tsp_get_flags.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_get_flags.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_get_flags.Tpo -c -o libtspi_la-tsp_get_flags.lo `test -f 'tsp_get_flags.c' || echo '$(srcdir)/'`tsp_get_flags.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_get_flags.Tpo $(DEPDIR)/libtspi_la-tsp_get_flags.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_get_flags.c' object='libtspi_la-tsp_get_flags.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_get_flags.lo `test -f 'tsp_get_flags.c' || echo '$(srcdir)/'`tsp_get_flags.c + +libtspi_la-obj_pcrs.lo: obj_pcrs.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-obj_pcrs.lo -MD -MP -MF $(DEPDIR)/libtspi_la-obj_pcrs.Tpo -c -o libtspi_la-obj_pcrs.lo `test -f 'obj_pcrs.c' || echo '$(srcdir)/'`obj_pcrs.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-obj_pcrs.Tpo $(DEPDIR)/libtspi_la-obj_pcrs.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='obj_pcrs.c' object='libtspi_la-obj_pcrs.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-obj_pcrs.lo `test -f 'obj_pcrs.c' || echo '$(srcdir)/'`obj_pcrs.c + +libtspi_la-tsp_pcr.lo: tsp_pcr.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_pcr.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_pcr.Tpo -c -o libtspi_la-tsp_pcr.lo `test -f 'tsp_pcr.c' || echo '$(srcdir)/'`tsp_pcr.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_pcr.Tpo $(DEPDIR)/libtspi_la-tsp_pcr.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_pcr.c' object='libtspi_la-tsp_pcr.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_pcr.lo `test -f 'tsp_pcr.c' || echo '$(srcdir)/'`tsp_pcr.c + +libtspi_la-obj_hash.lo: obj_hash.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-obj_hash.lo -MD -MP -MF $(DEPDIR)/libtspi_la-obj_hash.Tpo -c -o libtspi_la-obj_hash.lo `test -f 'obj_hash.c' || echo '$(srcdir)/'`obj_hash.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-obj_hash.Tpo $(DEPDIR)/libtspi_la-obj_hash.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='obj_hash.c' object='libtspi_la-obj_hash.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-obj_hash.lo `test -f 'obj_hash.c' || echo '$(srcdir)/'`obj_hash.c + +libtspi_la-obj_encdata.lo: obj_encdata.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-obj_encdata.lo -MD -MP -MF $(DEPDIR)/libtspi_la-obj_encdata.Tpo -c -o libtspi_la-obj_encdata.lo `test -f 'obj_encdata.c' || echo '$(srcdir)/'`obj_encdata.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-obj_encdata.Tpo $(DEPDIR)/libtspi_la-obj_encdata.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='obj_encdata.c' object='libtspi_la-obj_encdata.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-obj_encdata.lo `test -f 'obj_encdata.c' || echo '$(srcdir)/'`obj_encdata.c + +libtspi_la-obj_rsakey.lo: obj_rsakey.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-obj_rsakey.lo -MD -MP -MF $(DEPDIR)/libtspi_la-obj_rsakey.Tpo -c -o libtspi_la-obj_rsakey.lo `test -f 'obj_rsakey.c' || echo '$(srcdir)/'`obj_rsakey.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-obj_rsakey.Tpo $(DEPDIR)/libtspi_la-obj_rsakey.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='obj_rsakey.c' object='libtspi_la-obj_rsakey.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-obj_rsakey.lo `test -f 'obj_rsakey.c' || echo '$(srcdir)/'`obj_rsakey.c + +libtspi_la-tsp_key.lo: tsp_key.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_key.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_key.Tpo -c -o libtspi_la-tsp_key.lo `test -f 'tsp_key.c' || echo '$(srcdir)/'`tsp_key.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_key.Tpo $(DEPDIR)/libtspi_la-tsp_key.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_key.c' object='libtspi_la-tsp_key.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_key.lo `test -f 'tsp_key.c' || echo '$(srcdir)/'`tsp_key.c + +libtspi_la-tspi_asn1.lo: tspi_asn1.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_asn1.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_asn1.Tpo -c -o libtspi_la-tspi_asn1.lo `test -f 'tspi_asn1.c' || echo '$(srcdir)/'`tspi_asn1.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_asn1.Tpo $(DEPDIR)/libtspi_la-tspi_asn1.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_asn1.c' object='libtspi_la-tspi_asn1.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_asn1.lo `test -f 'tspi_asn1.c' || echo '$(srcdir)/'`tspi_asn1.c + +libtspi_la-tspi_audit.lo: tspi_audit.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_audit.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_audit.Tpo -c -o libtspi_la-tspi_audit.lo `test -f 'tspi_audit.c' || echo '$(srcdir)/'`tspi_audit.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_audit.Tpo $(DEPDIR)/libtspi_la-tspi_audit.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_audit.c' object='libtspi_la-tspi_audit.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_audit.lo `test -f 'tspi_audit.c' || echo '$(srcdir)/'`tspi_audit.c + +libtspi_la-tsp_audit.lo: tsp_audit.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_audit.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_audit.Tpo -c -o libtspi_la-tsp_audit.lo `test -f 'tsp_audit.c' || echo '$(srcdir)/'`tsp_audit.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_audit.Tpo $(DEPDIR)/libtspi_la-tsp_audit.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_audit.c' object='libtspi_la-tsp_audit.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_audit.lo `test -f 'tsp_audit.c' || echo '$(srcdir)/'`tsp_audit.c + +libtspi_la-rpc_audit.lo: rpc/@RPC@/rpc_audit.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_audit.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_audit.Tpo -c -o libtspi_la-rpc_audit.lo `test -f 'rpc/@RPC@/rpc_audit.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_audit.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_audit.Tpo $(DEPDIR)/libtspi_la-rpc_audit.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_audit.c' object='libtspi_la-rpc_audit.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_audit.lo `test -f 'rpc/@RPC@/rpc_audit.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_audit.c + +libtspi_la-tsp_seal.lo: tsp_seal.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_seal.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_seal.Tpo -c -o libtspi_la-tsp_seal.lo `test -f 'tsp_seal.c' || echo '$(srcdir)/'`tsp_seal.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_seal.Tpo $(DEPDIR)/libtspi_la-tsp_seal.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_seal.c' object='libtspi_la-tsp_seal.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_seal.lo `test -f 'tsp_seal.c' || echo '$(srcdir)/'`tsp_seal.c + +libtspi_la-tspi_quote2.lo: tspi_quote2.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_quote2.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_quote2.Tpo -c -o libtspi_la-tspi_quote2.lo `test -f 'tspi_quote2.c' || echo '$(srcdir)/'`tspi_quote2.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_quote2.Tpo $(DEPDIR)/libtspi_la-tspi_quote2.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_quote2.c' object='libtspi_la-tspi_quote2.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_quote2.lo `test -f 'tspi_quote2.c' || echo '$(srcdir)/'`tspi_quote2.c + +libtspi_la-tsp_quote2.lo: tsp_quote2.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_quote2.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_quote2.Tpo -c -o libtspi_la-tsp_quote2.lo `test -f 'tsp_quote2.c' || echo '$(srcdir)/'`tsp_quote2.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_quote2.Tpo $(DEPDIR)/libtspi_la-tsp_quote2.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_quote2.c' object='libtspi_la-tsp_quote2.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_quote2.lo `test -f 'tsp_quote2.c' || echo '$(srcdir)/'`tsp_quote2.c + +libtspi_la-rpc_quote2.lo: rpc/@RPC@/rpc_quote2.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_quote2.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_quote2.Tpo -c -o libtspi_la-rpc_quote2.lo `test -f 'rpc/@RPC@/rpc_quote2.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_quote2.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_quote2.Tpo $(DEPDIR)/libtspi_la-rpc_quote2.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_quote2.c' object='libtspi_la-rpc_quote2.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_quote2.lo `test -f 'rpc/@RPC@/rpc_quote2.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_quote2.c + +libtspi_la-main.lo: gtk/main.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-main.lo -MD -MP -MF $(DEPDIR)/libtspi_la-main.Tpo -c -o libtspi_la-main.lo `test -f 'gtk/main.c' || echo '$(srcdir)/'`gtk/main.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-main.Tpo $(DEPDIR)/libtspi_la-main.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gtk/main.c' object='libtspi_la-main.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-main.lo `test -f 'gtk/main.c' || echo '$(srcdir)/'`gtk/main.c + +libtspi_la-support.lo: gtk/support.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-support.lo -MD -MP -MF $(DEPDIR)/libtspi_la-support.Tpo -c -o libtspi_la-support.lo `test -f 'gtk/support.c' || echo '$(srcdir)/'`gtk/support.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-support.Tpo $(DEPDIR)/libtspi_la-support.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gtk/support.c' object='libtspi_la-support.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-support.lo `test -f 'gtk/support.c' || echo '$(srcdir)/'`gtk/support.c + +libtspi_la-interface.lo: gtk/interface.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-interface.lo -MD -MP -MF $(DEPDIR)/libtspi_la-interface.Tpo -c -o libtspi_la-interface.lo `test -f 'gtk/interface.c' || echo '$(srcdir)/'`gtk/interface.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-interface.Tpo $(DEPDIR)/libtspi_la-interface.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gtk/interface.c' object='libtspi_la-interface.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-interface.lo `test -f 'gtk/interface.c' || echo '$(srcdir)/'`gtk/interface.c + +libtspi_la-callbacks.lo: gtk/callbacks.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-callbacks.lo -MD -MP -MF $(DEPDIR)/libtspi_la-callbacks.Tpo -c -o libtspi_la-callbacks.lo `test -f 'gtk/callbacks.c' || echo '$(srcdir)/'`gtk/callbacks.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-callbacks.Tpo $(DEPDIR)/libtspi_la-callbacks.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gtk/callbacks.c' object='libtspi_la-callbacks.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-callbacks.lo `test -f 'gtk/callbacks.c' || echo '$(srcdir)/'`gtk/callbacks.c + +libtspi_la-ssl_ui.lo: ssl_ui.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-ssl_ui.lo -MD -MP -MF $(DEPDIR)/libtspi_la-ssl_ui.Tpo -c -o libtspi_la-ssl_ui.lo `test -f 'ssl_ui.c' || echo '$(srcdir)/'`ssl_ui.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-ssl_ui.Tpo $(DEPDIR)/libtspi_la-ssl_ui.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ssl_ui.c' object='libtspi_la-ssl_ui.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-ssl_ui.lo `test -f 'ssl_ui.c' || echo '$(srcdir)/'`ssl_ui.c + +libtspi_la-tspi_nv.lo: tspi_nv.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_nv.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_nv.Tpo -c -o libtspi_la-tspi_nv.lo `test -f 'tspi_nv.c' || echo '$(srcdir)/'`tspi_nv.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_nv.Tpo $(DEPDIR)/libtspi_la-tspi_nv.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_nv.c' object='libtspi_la-tspi_nv.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_nv.lo `test -f 'tspi_nv.c' || echo '$(srcdir)/'`tspi_nv.c + +libtspi_la-obj_nv.lo: obj_nv.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-obj_nv.lo -MD -MP -MF $(DEPDIR)/libtspi_la-obj_nv.Tpo -c -o libtspi_la-obj_nv.lo `test -f 'obj_nv.c' || echo '$(srcdir)/'`obj_nv.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-obj_nv.Tpo $(DEPDIR)/libtspi_la-obj_nv.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='obj_nv.c' object='libtspi_la-obj_nv.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-obj_nv.lo `test -f 'obj_nv.c' || echo '$(srcdir)/'`obj_nv.c + +libtspi_la-tsp_nv.lo: tsp_nv.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_nv.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_nv.Tpo -c -o libtspi_la-tsp_nv.lo `test -f 'tsp_nv.c' || echo '$(srcdir)/'`tsp_nv.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_nv.Tpo $(DEPDIR)/libtspi_la-tsp_nv.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_nv.c' object='libtspi_la-tsp_nv.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_nv.lo `test -f 'tsp_nv.c' || echo '$(srcdir)/'`tsp_nv.c + +libtspi_la-rpc_nv.lo: rpc/@RPC@/rpc_nv.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_nv.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_nv.Tpo -c -o libtspi_la-rpc_nv.lo `test -f 'rpc/@RPC@/rpc_nv.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_nv.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_nv.Tpo $(DEPDIR)/libtspi_la-rpc_nv.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_nv.c' object='libtspi_la-rpc_nv.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_nv.lo `test -f 'rpc/@RPC@/rpc_nv.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_nv.c + +libtspi_la-tspi_delegate.lo: tspi_delegate.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_delegate.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_delegate.Tpo -c -o libtspi_la-tspi_delegate.lo `test -f 'tspi_delegate.c' || echo '$(srcdir)/'`tspi_delegate.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_delegate.Tpo $(DEPDIR)/libtspi_la-tspi_delegate.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_delegate.c' object='libtspi_la-tspi_delegate.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_delegate.lo `test -f 'tspi_delegate.c' || echo '$(srcdir)/'`tspi_delegate.c + +libtspi_la-tsp_delegate.lo: tsp_delegate.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tsp_delegate.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tsp_delegate.Tpo -c -o libtspi_la-tsp_delegate.lo `test -f 'tsp_delegate.c' || echo '$(srcdir)/'`tsp_delegate.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tsp_delegate.Tpo $(DEPDIR)/libtspi_la-tsp_delegate.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tsp_delegate.c' object='libtspi_la-tsp_delegate.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tsp_delegate.lo `test -f 'tsp_delegate.c' || echo '$(srcdir)/'`tsp_delegate.c + +libtspi_la-obj_delfamily.lo: obj_delfamily.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-obj_delfamily.lo -MD -MP -MF $(DEPDIR)/libtspi_la-obj_delfamily.Tpo -c -o libtspi_la-obj_delfamily.lo `test -f 'obj_delfamily.c' || echo '$(srcdir)/'`obj_delfamily.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-obj_delfamily.Tpo $(DEPDIR)/libtspi_la-obj_delfamily.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='obj_delfamily.c' object='libtspi_la-obj_delfamily.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-obj_delfamily.lo `test -f 'obj_delfamily.c' || echo '$(srcdir)/'`obj_delfamily.c + +libtspi_la-rpc_delegate.lo: rpc/@RPC@/rpc_delegate.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_delegate.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_delegate.Tpo -c -o libtspi_la-rpc_delegate.lo `test -f 'rpc/@RPC@/rpc_delegate.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_delegate.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_delegate.Tpo $(DEPDIR)/libtspi_la-rpc_delegate.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_delegate.c' object='libtspi_la-rpc_delegate.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_delegate.lo `test -f 'rpc/@RPC@/rpc_delegate.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_delegate.c + +libtspi_la-tspi_cmk.lo: tspi_cmk.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-tspi_cmk.lo -MD -MP -MF $(DEPDIR)/libtspi_la-tspi_cmk.Tpo -c -o libtspi_la-tspi_cmk.lo `test -f 'tspi_cmk.c' || echo '$(srcdir)/'`tspi_cmk.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-tspi_cmk.Tpo $(DEPDIR)/libtspi_la-tspi_cmk.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tspi_cmk.c' object='libtspi_la-tspi_cmk.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-tspi_cmk.lo `test -f 'tspi_cmk.c' || echo '$(srcdir)/'`tspi_cmk.c + +libtspi_la-obj_migdata.lo: obj_migdata.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-obj_migdata.lo -MD -MP -MF $(DEPDIR)/libtspi_la-obj_migdata.Tpo -c -o libtspi_la-obj_migdata.lo `test -f 'obj_migdata.c' || echo '$(srcdir)/'`obj_migdata.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-obj_migdata.Tpo $(DEPDIR)/libtspi_la-obj_migdata.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='obj_migdata.c' object='libtspi_la-obj_migdata.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-obj_migdata.lo `test -f 'obj_migdata.c' || echo '$(srcdir)/'`obj_migdata.c + +libtspi_la-rpc_cmk.lo: rpc/@RPC@/rpc_cmk.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -MT libtspi_la-rpc_cmk.lo -MD -MP -MF $(DEPDIR)/libtspi_la-rpc_cmk.Tpo -c -o libtspi_la-rpc_cmk.lo `test -f 'rpc/@RPC@/rpc_cmk.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_cmk.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtspi_la-rpc_cmk.Tpo $(DEPDIR)/libtspi_la-rpc_cmk.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rpc/@RPC@/rpc_cmk.c' object='libtspi_la-rpc_cmk.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtspi_la_CFLAGS) $(CFLAGS) -c -o libtspi_la-rpc_cmk.lo `test -f 'rpc/@RPC@/rpc_cmk.c' || echo '$(srcdir)/'`rpc/@RPC@/rpc_cmk.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-libLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/tspi/daa/Makefile.am b/src/tspi/daa/Makefile.am new file mode 100644 index 0000000..b02bbde --- /dev/null +++ b/src/tspi/daa/Makefile.am @@ -0,0 +1,31 @@ +bin_PROGRAMS=issuer_setup key_verification test test_tpm test_join test_sign +#todel + +test_SOURCES=big_integer/bi_gmp.c big_integer/bi_openssl.c big_integer/bi.c utils/list.c big_integer/test/test.c big_integer/test/multi_exp.c +test_CFLAGS=-I../../include/daa -I../../include -DBI_DEBUG -g -DAPPID=\"BI\" +test_LDFLAGS=-lcrypto + +issuer_setup_SOURCES = daa_issuer/issuer_setup.c +issuer_setup_CFLAGS=-I../../include/daa -I../../include -DBI_DEBUG -DAPPID=\"DAA_ISSUER_SETUP\" +issuer_setup_LDFLAGS=-lcrypto ../libtspi.la ../libdaa.la + +key_verification_SOURCES=daa_issuer/key_verification.c +key_verification_CFLAGS=-I../../include/daa -I../../include -DBI_DEBUG -DAPPID=\"DAA_KEY_VERIFICATION\" +key_verification_LDFLAGS=-lcrypto ../libtspi.la ../libdaa.la + +test_tpm_SOURCES = daa_platform/test.c +test_tpm_CFLAGS=-I../../include/daa -I../../include +test_tpm_LDFLAGS=-lcrypto ../libtspi.la ../libdaa.la + +test_join_SOURCES = daa_platform/test_join.c +test_join_CFLAGS=-I../../include/daa -I../../include -DBI_DEBUG -DAPPID=\"DAA_JOIN\" +test_join_LDFLAGS=-lcrypto ../libtspi.la ../libdaa.la + +test_sign_SOURCES = test_sign.c +test_sign_CFLAGS=-I../../include/daa -I../../include -DBI_DEBUG -DAPPID=\"DAA_JOIN\" +test_sign_LDFLAGS=-lcrypto ../libtspi.la ../libdaa.la + +#todel_SOURCES = todel.c +#todel_CFLAGS=-I../../include/daa -I../../include -DBI_DEBUG -DAPPID=\"DAA_JOIN\" +#todel_LDFLAGS=-lcrypto ../libtspi.la ../libdaa.la + diff --git a/src/tspi/daa/big_integer/bi.c b/src/tspi/daa/big_integer/bi.c new file mode 100644 index 0000000..b86b2c1 --- /dev/null +++ b/src/tspi/daa/big_integer/bi.c @@ -0,0 +1,237 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + +#include <bi.h> + +#include "tcslog.h" + +#undef INLINE_DECL +#define INLINE_DECL + +/*********************************************************************************** + CONSTANT +*************************************************************************************/ + +bi_t bi_0; +bi_t bi_1; +bi_t bi_2; + +/*********************************************************************************** + WORK VARIABLE +*************************************************************************************/ + +// Buffer to load bi from a file . A static field is used, this should not be +// refere in any SPI calls. +#define BUFFER_SIZE 10000 +static char buffer[BUFFER_SIZE]; // used for loading bi + +#define SAFETY_PARAM 80 + +// keep the list of allocated memory, usually used for the format functions +list_ptr allocs = NULL; + +/*********************************************************************************** + DUMP LIB +*************************************************************************************/ + +// !! to use only for debugging +// do not used it in the same call, as a static buffer is used +char *dump_byte_array(int len, unsigned char *array) { + int i, j=0; + char c, str[3]; + + for( i=0; i<len; i++) { + c = array[i]; + sprintf( str, "%02X", (int)(c & 0xFF)); + buffer[j] = str[0]; + buffer[j+1] = str[1]; + j+=2; + } + buffer[j] = 0; + return buffer; +} + +/* convert <strings> and return it into a byte array <result> of length <length> */ +unsigned char *retrieve_byte_array( int *len, const char *strings) { + int index_str = 0, index_result = 0; + int str_len = strlen( strings); + char read_buffer[3]; + int c; + unsigned char *result; + + read_buffer[2]=0; + *len = ( str_len >> 1); + #ifdef BI_DEBUG + printf("[%s]\n", strings); + printf("[retrieve_byte_array] strlen=%d len=%d\n", str_len, *len); + #endif + result = (unsigned char *)malloc( *len+1); + if( result == NULL) { + LogError("malloc of %d bytes failed", *len+1); + return NULL; + } + if( (str_len & 1) ==1) { + // impair => 1 12 23 -> 01 12 23 + read_buffer[0]='0'; + read_buffer[1]=strings[index_str++]; + sscanf( read_buffer, "%2X", &c); + #ifdef BI_DEBUG + printf("[c'=%2X|%s]", (int)(c & 0xFF), read_buffer); + #endif + result[index_result++] = c&0xFF; + (*len)++; + } + while( index_str < str_len) { + read_buffer[0] = strings[ index_str++]; + read_buffer[1] = strings[ index_str++]; + sscanf( read_buffer, "%02X", &c); + #ifdef BI_DEBUG + printf("[c'=%2X|%s]", (int)(c & 0xFF), read_buffer); + #endif + result[index_result++] = c&0xFF; + } + return result; +} + +/* create a <big integer> array */ +INLINE_DECL void bi_new_array( bi_array array, const int length) { + int i=0; + + bi_new_array2( array, length); + if( array->array == NULL) return; + for( i = 0; i< length; i++) { + array->array[i] = bi_new_ptr(); + } +} + +/* create a <big integer> array */ +INLINE_DECL void bi_new_array2( bi_array array, const int length) { + array->length = length; + array->array = (bi_ptr *)malloc( sizeof(bi_ptr) * length); + if( array->array == NULL) { + LogError("malloc of %d bytes failed", sizeof(bi_ptr)*length); + return; + } +} + +/* free resources allocated to the big integer <i> */ +INLINE_DECL void bi_free_array(bi_array array) { + int length = array->length; + int i=0; + + for( i = 0; i< length; i++) { + bi_free_ptr( array->array[i]); + } + free( array->array); +} + +/* copy length pointers from the array <src, offset_src> to array <dest, offset_dest> */ +INLINE_DECL void bi_copy_array(bi_array_ptr src, + int offset_src, + bi_array_ptr dest, + int offset_dest, + int length) { + int i=0; + + for( i = 0; i< length; i++) { + dest->array[ offset_dest + i] = src->array[ offset_src + i]; + } +} + +/* debug function -> dump a field of type bi_array */ +void dump_bi_array( char *field, const bi_array_ptr array) { + int i; + + for( i=0; i<array->length; i++) { + printf("%s->array[%d] = %s\n", field, i, bi_2_hex_char(array->array[i])); + } +} + +/*********************************************************************************** + SAFE RANDOM +*************************************************************************************/ + +/* Returns a random number in the range of [0,element-1] */ +bi_ptr compute_random_number( bi_ptr result, const bi_ptr element) { + bi_urandom( result, bi_length( element) + SAFETY_PARAM); + bi_mod( result, result, element); + return result; +} + +/*********************************************************************************** + SAVE / LOAD +*************************************************************************************/ + +/* load an big integer from an open file handler */ +void bi_load( bi_ptr bi, FILE *file) { + int i=0; + char c; + + fgets( buffer, BUFFER_SIZE, file); + do { + c = buffer[i]; + i++; + } while( c != 0 && c != ' '); + buffer[i-1] = 0; + bi_set_as_hex( bi, buffer); +} + +/* load an big integer array from an open file handler */ +void bi_load_array( bi_array_ptr array, FILE *file) { + int i, j = 0, length; + char c; + + fgets( buffer, BUFFER_SIZE, file); + do { + c = buffer[ j]; + j++; + } while( c != 0 && c != ' '); + buffer[ j -1] = 0; + sscanf( buffer, "%d", &length); + bi_new_array( array, length); + for( i=0; i<array->length; i++) { + bi_load( array->array[i], file); + } +} + +/* save an big integer to an open file handler */ +void bi_save( const bi_ptr bi, const char *name, FILE *file) { + fprintf( file, "%s # %s [%ld]\n", bi_2_hex_char( bi), name, bi_nbin_size( bi)); +} + +/* save an big integer array to an open file handler */ +void bi_save_array( const bi_array_ptr array, const char *name, FILE *file) { + int i; + char new_name[100]; + + fprintf(file, "%d # %s.length\n", array->length, name); + for( i=0; i<array->length; i++) { + sprintf( new_name, "%s[%d]", name, i); + bi_save( array->array[i], new_name, file); + } +} + +/* convert <bi> to a byte array of length result, the beginning of */ +/* this buffer is feel with '0' if needed */ +void bi_2_byte_array( unsigned char *result, int length, bi_ptr bi) { + int i, result_length; + + bi_2_nbin1( &result_length, buffer, bi); + int delta = length - result_length; + #ifdef BI_DEBUG + fprintf( stderr, "[bi_2_byte_array] result_length=%d length=%d\n", result_length, length); + #endif + if( delta < 0) { + LogError( "[bi_2_byte_array] asked length:%d found:%d\n", length, result_length); + return; + } + for( i=0; i<delta; i++) result[i] = 0; + for( ; i<length; i++) result[ i] = buffer[ i - delta]; +} diff --git a/src/tspi/daa/big_integer/bi_gmp.c b/src/tspi/daa/big_integer/bi_gmp.c new file mode 100644 index 0000000..f03bf4c --- /dev/null +++ b/src/tspi/daa/big_integer/bi_gmp.c @@ -0,0 +1,261 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + +#ifdef BI_GMP + +#include <time.h> +#include <stdio.h> +#include <stdlib.h> + +#include <bi.h> + +#undef INLINE_DECL +#define INLINE_DECL + +gmp_randstate_t state; + +/* + reps controls how many tests should be done in mpz_probable_prime_p: + 5 to 10 are reasonable number +*/ +static int reps = 20; + +static int initialized = 0; +void * (*bi_alloc)(size_t size); + +/*********************************************************************************** + BITS OPERATION +*************************************************************************************/ + +// for conversion from and to byte[] see mpz_export and mpz_import + +/* return the size of a network byte order representation of <i> */ +long bi_nbin_size(const bi_ptr i) { + int word_size = 1; // 1 byte per word + int numb = 8 * word_size - 0; + int count = (mpz_sizeinbase ( i, 2) + numb-1) / numb; + + return count * word_size; +} + +/* return a BYTE * - in network byte order - and update the length <length> */ +unsigned char *bi_2_nbin( int *length, const bi_ptr i) { + unsigned char *buffer = (unsigned char *)bi_alloc( bi_nbin_size( i)); + + if( buffer == NULL) return NULL; + mpz_export(buffer, length, 1, 1, 1, 0, i); + return buffer; +} + +/* return a BYTE * - in network byte order - and update the length <length> */ +/* different from bi_2_nbin: you should reserve enough memory for the storage */ +void bi_2_nbin1( int *length, unsigned char *buffer, const bi_ptr i) { + mpz_export(buffer, length, 1, 1, 1, 0, i); +} + +/* return a bi_ptr that correspond to the big endian encoded BYTE array of length <n_length> */ +INLINE_DECL bi_ptr bi_set_as_nbin( const unsigned long length, const unsigned char *buffer) { + bi_ptr ret = bi_new_ptr(); + + if( ret == NULL) return NULL; + mpz_import( ret, length, 1, 1, 1, 0, buffer); + return ret; +} + + +/*********************************************************************************** + BASIC MATH OPERATION +*************************************************************************************/ + +/* multiple-exponentiation */ +/* <result> := mod( Multi( <g>i, <e>i), number of byte <m>) with 0 <= i <= <n> */ +bi_ptr bi_multi_mod_exp( bi_ptr result, + const int n, + const bi_t g[], + const long e[], + const int m) { + mpz_t temp, bi_m; + int i; + + mpz_init( temp); + mpz_init( bi_m); + mpz_set_si( bi_m, m); + // result := (g[0] ^ e[0]) mod m + mpz_powm_ui( result, g[0], e[0], bi_m); + for( i=1; i<n; i++) { + // temp := (g[i] ^ e[i]) mod bi_m + mpz_powm_ui( temp, g[i], e[i], bi_m); + // result := result * temp + mpz_mul( result, result, temp); + } + mpz_mod_ui( result, result, m); + mpz_clear( bi_m); + mpz_clear( temp); + return result; +} + +/*********************************************************************************** + NUMBER THEORIE OPERATION +*************************************************************************************/ +/* generate prime number of <length> bits */ +INLINE_DECL bi_ptr bi_generate_prime( bi_ptr result, const long length) { + do { + mpz_urandomb( result, state, length); // i := random( length) + bi_setbit( result, 0); + bi_setbit( result, length - 1); + bi_setbit( result, length - 2); + mpz_nextprime( result, result); // i := nextPrime( i) + } while( mpz_sizeinbase( result, 2) != (unsigned long)length && + bi_is_probable_prime( result) ); + return result; +} + +/* generate a safe prime number of <length> bits */ +/* by safe we mean a prime p so that (p-1)/2 is also prime */ +INLINE_DECL bi_ptr bi_generate_safe_prime( bi_ptr result, long length) { + mpz_t temp; + + mpz_init(temp); + do { + bi_generate_prime( result, length); + mpz_sub_ui( temp, result, 1); // temp := result - 1 + mpz_div_2exp( temp, temp, 1); // temp := temp / 2 + } while( mpz_probab_prime_p( temp, 10) == 0); +#ifdef BI_DEBUG + printf("GENERATE SAFE PRIME DONE");fflush(stdout); +#endif + mpz_clear( temp); + return result; +} + +/* return true if <i> is a probably prime */ +INLINE_DECL int bi_is_probable_prime( bi_ptr i) { + /* + This function does some trial divisions and after some Miller-Rabin probabilistic + primality tests. The second parameter controls how many tests should be done, + 5 to 10 are reasonable number + */ + return mpz_probab_prime_p( i, reps)>=1 ? 1 : 0; +} + +/* return in <result> the greatest common divisor of <a> and <b> */ +/* <result> := gcd( <a>, <b>) */ +INLINE_DECL bi_ptr bi_gcd( bi_ptr result, bi_ptr a, bi_ptr b) { + // result := gcd( a, b) + mpz_gcd( result, a, b); + return result; +} + + +/*********************************************************************************** + INIT/RELEASE LIBRARY +*************************************************************************************/ + +/* bi_alloc_p allocation function used only for exporting a bi struct, so for bi_2_nbin +if define as NULL, a stdlib malloc() will be used */ +void bi_init( void * (*bi_alloc_p)(size_t size)) { + time_t start; + unsigned long seed; + FILE *f; +#ifdef INTERACTIVE + int c, i; +#endif + + if( initialized == 1) return; + if( bi_alloc_p == NULL) bi_alloc = &malloc; + else bi_alloc = bi_alloc_p; + mpz_init( bi_0); + mpz_set_ui( bi_0, 0); + mpz_init( bi_1); + mpz_set_ui( bi_1, 1); + mpz_init( bi_2); + mpz_set_ui( bi_2, 2); + allocs = list_new(); + if( allocs == NULL) { + LogError("malloc of list failed"); + return; + } +#ifdef BI_DEBUG + printf("bi_init() -> gmp lib\n"); +#endif + time( &start); + // first try /dev/random, the most secure random generator + f = fopen("/dev/random", "r"); + // in case of failure, but les secure :( + if( f== NULL) f = fopen("/dev/urandom", "r"); + if( f != NULL) { + fread( &seed, sizeof(unsigned long int), 1, f); + fclose(f); + } +#ifdef INTERACTIVE + else { + printf("! devices /dev/random and /dev/urandom not found\n"); + printf("type some characters to generate a random seed (follow by enter)\n"); + fflush(stdout); + i=0; + while( (c = fgetc(stdin)) != 10) { + time_t temps; + time( &temps); + seed += temps +( c << i); + i++; + } + time_t temps; + time( &temps); + seed += temps; +#ifdef BI_DEBUG + printf("temps=%lx\n", temps - start); +#endif // BI_DEBUG + seed = (long)( temps * start); + } +#endif // INTERACTIVE +#ifdef BI_DEBUG + printf("seed=%lx\n", seed); +#endif + gmp_randinit_default( state); + gmp_randseed_ui( state, seed); + initialized = 1; +} + +void bi_release(void) { + if( initialized) { + bi_flush_memory(); + bi_free( bi_0); + bi_free( bi_1); + bi_free( bi_2); + initialized = 0; + } +} +void bi_flush_memory(void) { + node_t *current; + list_ptr list = allocs; + + if( list->head == NULL) return; // list is empty + else { + current = list->head; // go to first node + do { + LogDebug("[flush memory] free %lx\n", current->obj); + free( current->obj); + current = current->next; // traverse through the list + } while(current != NULL); // until current node is NULL + } + list_freeall( allocs); + allocs = list_new(); + if( allocs == NULL) { + LogError("malloc of list failed"); + return; + } +} + + +int bi_is_initialized(void) { + return initialized; +} + +#endif diff --git a/src/tspi/daa/big_integer/bi_openssl.c b/src/tspi/daa/big_integer/bi_openssl.c new file mode 100644 index 0000000..50ef030 --- /dev/null +++ b/src/tspi/daa/big_integer/bi_openssl.c @@ -0,0 +1,181 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + +#ifdef BI_OPENSSL + +#define INSIDE_LIB + +#include <time.h> +#include <stdio.h> +#include <stdlib.h> + +#include <bi.h> + +#include "tcslog.h" + +#undef INLINE_DECL +#define INLINE_DECL + +#include <string.h> +#include <openssl/rand.h> + +BN_CTX *context; +static int initialized = 0; + +void * (*bi_alloc)(size_t size); + +/* return true if <i> is a probably prime */ +INLINE_DECL int bi_is_probable_prime( const bi_ptr i) { + /* + * start tests using some small prime numbers. Continue by performing a Miller-Rabin + * probabilistic primality test with checks iterations, and with some iterations that + * yields a false positive rate of at most 2^-80 for random input. + * return: + * 0 if the number is composite + * 1 if it is prime with an error probability of less than 0.25^checks, and on error. + */ + return BN_is_prime_fasttest( i, BN_prime_checks, NULL, context, NULL, 1); +} + +/* <result> := ( <g> ^ <e> ) mod <m> */ +INLINE_DECL bi_ptr bi_mod_exp_si( bi_ptr result, const bi_ptr g, const bi_ptr e, const long m) { + bi_t bi_tmp; + + bi_new( bi_tmp); + BN_set_word( bi_tmp, m); +#ifdef BI_DEBUG + printf("[bi_mod_exp] (g=%s ^ e=%s) mod=%s\n", + BN_bn2dec( g), + BN_bn2dec( e), + BN_bn2dec( bi_tmp)); +#endif + BN_mod_exp( result, g, e, bi_tmp, context); // result := (g ^ e) mod bi_tmp9 +#ifdef BI_DEBUG + printf("[bi_mod_exp] res=%s\n", BN_bn2dec( result)); +#endif + bi_free( bi_tmp); + return result; +} + +/* multiple-exponentiation */ +/* <result> := mod( Multi( <g>i, <e>i), number of byte <m>) with 0 <= i <= <n> */ +bi_ptr bi_multi_mod_exp( bi_ptr result, + const int n, + const bi_t g[], + const long e[], + const int m +) { + BIGNUM *temp = BN_new(); + BIGNUM *bi_m = BN_new(); + BIGNUM *bi_e = BN_new(); + int i; + + BN_set_word( bi_m, m); + BN_set_word( bi_e, e[0]); + // result := (g[0] ^ e[0]) mod bi_m + BN_mod_exp( result, g[0], bi_e, bi_m, context); + for( i=1; i<n; i++) { + BN_set_word( bi_e, e[i]); + // temp := (g[i] ^ e[i]) mod bi_m + BN_mod_exp( temp, g[i], bi_e, bi_m, context); + // result := result * temp + BN_mul( result, result, temp, context); + } + BN_mod( result, result, bi_m, context); + BN_free(bi_e); + BN_free(bi_m); + BN_free(temp); + return result; +} + + +/*********************************************************************************** + INIT/RELEASE LIBRARY +************************************************************************************/ + +/* bi_alloc_p allocation function used only for exporting a bi struct, +so for bi_2_nbin? for example. if define as NULL, a stdlib malloc() will be used +*/ +void bi_init( void * (*bi_alloc_p)(size_t size)) { + if( initialized == 1) return; + if( bi_alloc_p == NULL) bi_alloc = &malloc; + else bi_alloc = bi_alloc_p; + bi_new( bi_0); + bi_set_as_si( bi_1, 0); + bi_new( bi_1); + bi_set_as_si( bi_1, 1); + bi_new( bi_2); + bi_set_as_si( bi_2, 2); + allocs = list_new(); + if( allocs == NULL) { + LogError("malloc of list failed"); + return; + } + LogDebug("bi_init() -> openssl lib\n"); + LogDebug("bi_init() -> seed status = %d\n", RAND_status()); + context = BN_CTX_new(); + if( RAND_status() != 1) { + LogError("! PRNG has not been seeded with enough data\n"); +#ifdef INTERACTIVE + printf("type some characters to regenerate a random seed\n"); + fflush(stdout); + int c, i=0, seed; + char str[2] = "a"; + while( RAND_status() !=1 ) { + c = fgetc(stdin); + time_t temps; + time( &temps); + seed += temps +( c << i); + i++; + str[0]=c; + RAND_seed( str, 1); + } +#endif + } + initialized = 1; +} + +void bi_release(void) { + if( initialized) { + bi_flush_memory(); + bi_free( bi_0); + bi_free( bi_1); + bi_free( bi_2); + BN_CTX_free( context); + initialized = 0; + } +} + +void bi_flush_memory(void) { + node_t *current; + list_ptr list = allocs; + + if( list->head == NULL) return; // list is empty + else { + current = list->head; // go to first node + do { + LogDebug("[flush memory] free %lx\n", (long)current->obj); + free( current->obj); + current = current->next; // traverse through the list + } while(current != NULL); // until current node is NULL + } + list_freeall( allocs); + allocs = list_new(); + if( allocs == NULL) { + LogError("malloc of list failed"); + return; + } +} + +int bi_is_initialized(void) { + return initialized; +} + +#endif diff --git a/src/tspi/daa/big_integer/test/Makefile.am b/src/tspi/daa/big_integer/test/Makefile.am new file mode 100644 index 0000000..d631c2a --- /dev/null +++ b/src/tspi/daa/big_integer/test/Makefile.am @@ -0,0 +1,9 @@ +bin_PROGRAMS = test + + +test_SOURCES=test.c multi_exp.c ../bi_gmp.c ../bi_openssl.c ../bi.c \ + ../../../include/bi.h ../../../include/bi_openssl.h ../../../include/bi_gmp.h +test_CFLAGS=-G + +# test_CFLAGS=-I../../../include -DBI_OPENSSL + diff --git a/src/tspi/daa/big_integer/test/multi_exp.c b/src/tspi/daa/big_integer/test/multi_exp.c new file mode 100644 index 0000000..2ff80fc --- /dev/null +++ b/src/tspi/daa/big_integer/test/multi_exp.c @@ -0,0 +1,29 @@ +#include <stdio.h> + +#include <bi.h> + +// use standard C definition to avoid .h +int test_exp_multi(void) { + bi_t result; + bi_t g[3]; + unsigned long e[3]; + + bi_new( result); + bi_new( g[0]); + bi_new( g[1]); + bi_new( g[2]); + // result = (2^2 * 5^4 * 7^7) mod 56 -> should give 28 + bi_set_as_dec( g[0], "2"); + bi_set_as_dec( g[1], "5"); + bi_set_as_dec( g[2], "7"); + e[0] = 2L; + e[1] = 4L; + e[2] = 7L; + bi_multi_mod_exp( result, 3, g, e, 56); + printf("multi-exponentiation <result>=%s\n", bi_2_dec_char(result)); + bi_free( g[0]); + bi_free( g[1]); + bi_free( g[2]); + bi_free( result); + return 0; +} diff --git a/src/tspi/daa/big_integer/test/test.c b/src/tspi/daa/big_integer/test/test.c new file mode 100644 index 0000000..4cc3a7f --- /dev/null +++ b/src/tspi/daa/big_integer/test/test.c @@ -0,0 +1,296 @@ +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> + +#include <bi.h> + +/* for the logging system used by TSS */ +setenv("TCSD_FOREGROUND", "1", 1); + + /* + * standard bit length extension to obtain a uniformly distributed number + * [0,element] + */ +int test_exp_multi(void); + +void foo (bi_t result, const bi_ptr param, unsigned long n) { + unsigned long i; + + bi_set( result, param); + bi_mul_si( result, result, n); + for (i = 1; i < n; i++) bi_add_si( result, result, i*7); +} + +void *my_malloc(size_t size) { + void *ret = malloc( size); + + printf("my_malloc() -> %ld\n", (long)ret); + return ret; +} + + /** + * Returns a random number in the range of [0,element-1]. + * + * @param element + * the upper limit + * @param random + * the secure random source + * @return the random number + */ +void computeRandomNumber(bi_t res, const bi_ptr element) { + int length = 80 + bi_length( res); // give the length + bi_urandom( res, length); // res = random( of length); + int element_length = bi_length( element); + bi_mod_si( res, res, element_length); // res = res mod <number byte of element> +} + +int main (int argc, char **argv) { + bi_t bi_tmp, bi_tmp1, bi_tmp2, bi_tmp3, bi_tmp4, bi_tmp5, bi_tmp6; + bi_t r; + bi_t n; + int i; + unsigned char result1[5]; + int len; + char *byte_array; + FILE *file; + unsigned char ret[] = { (unsigned char)1, 0, (unsigned char)254 }; + int length; + unsigned char *buffer; + unsigned char byte; + bi_ptr nn; + + bi_init( &my_malloc); + printf("test(%s,%s)\n", __DATE__, __TIME__); + #ifdef BI_GMP + printf("using BMP\n"); + #endif + #ifdef BI_OPENSSL + printf("using OPENSSL\n"); + #endif + + bi_new( bi_tmp); + bi_new( bi_tmp1); + bi_new( bi_tmp2); + bi_new( bi_tmp3); + bi_new( bi_tmp4); + bi_new( bi_tmp5); + bi_new( bi_tmp6); + bi_new( n); + bi_new( r); + bi_set_as_hex( n, "75E8F38669C531EB78C7ACD62CCDEFFB5E5BE15E2AA55B3AD28B1A35F6E937097CE09A49C689AC335FBA669205CEF209275CFF273F8F81C5B864E5029EECDFA0743BC15D6E4D2C2CB0DED2DC7119A7E0D61669D417BB3B12BA1D10FD40326A49CA6C9E77F8585F25D8C897D9C73284152E103582C018C964F02ADDBA56CB1161A949AAE2847ADE8BC1152716C8B4AF37A87011C2569F646FD3EDA83099048B9525A6401C47A372F3EA43C91066AD5851AE11DEF1EAC7108FFB06AD94D0B849C339A5E8793C4C054456D3D22D30ACCCF7EF33EF7A7D65799E7908D95B0538A9EFC91BF104CE5008D79625394DB1E5883B2F202B95320BBD868BF65C996FC0DFC5"); + bi_set_as_hex( r, "35A624E6607CFD37162C6052547450B2267ECC749F10CDAEB5C294491321EEB47CA0229F423ADCEF3FA7806F5C4DB3C3445D8E7039EBC457149A1343BECF3B1078385C06EE74351A476BE0D5203633C81F7B8D68548DB763F0C096B20615B6016C180291EF32CC064A173BB22F6B46B3240ACC0B50D8338757FA28D5B0313BC4201CD2B35472842E71994C8FCA557B08004B2495304D13A93D796134BB8078E2EE371707DE5809D72474A7CCE1F865ECD8876105D3DB9AFA9426052D0120C755C60F56A0C0F30FAED2053CEB3129FAB6F57F6E209A8E7B2A559D734B339E19E1F2A147BC94DB2FF491CB5ACCEEEED7F2EA75AFF7CAD33E1E420A09135D9C5C1F"); + DUMP_BI( n); + DUMP_BI( r); + printf("big number n=n*r\n"); + bi_mul( n, n, r); + DUMP_BI( n); + bi_set_as_hex( r, "D7E7028DA181DADAC29C95143C865702453465115AFA7576AADF1E57DD84DA7FF4C8F66530D1E9D1AB69BC12342B89FA0A9755F9F4EE1DA445D50016CEF50622ED905CC9B987FCC7910CAA841641814C1994BC442A15CB05FE5C145626F1454E90435FBC6A529856EF29BDBCBFCB62FB69EDBD11DC33357667867278E1679EABCDBEEA02E9A6911804DF47ACA6B2D63A31E258AD542D71A8178A5E072F5E221EADBB10E16D5533AE427101FF94C5967575FABCD18305C5F15C103CEA1A8ACD01898E88426EDA7C0DF58AA48435808A840F6EEE1D7205D33F356E20FE0D4136B401BF386F11869C3CE4A808B96435694748EF3706F58756548A71E4CF4D2BE157"); + bi_mod( n, n, r); + printf("mod big number n=n mod r\n"); + DUMP_BI( n); + if( bi_get_si( bi_set_as_si( n, 13)) != 13) { + printf("!!! bi_set_as_si 13(%s) = 13\n", bi_2_dec_char( n )); + exit(-1); + } + if( bi_get_si( bi_set_as_si( n, -13)) != -13) { + printf("!!! bi_set_as_si -13(%s) = -13\n", bi_2_dec_char( n )); + exit(-1); + } + if( bi_get_si( bi_inc(bi_set_as_si( n, 13))) != 14) { + puts("!!! bi_inc 13++ = 14\n"); + exit(-1); + } + if( bi_get_si( bi_dec(bi_set_as_si( n, 13))) != 12) { + puts("!!! bi_dec 13-- = 12\n"); + exit(-1); + } + if( bi_get_si( bi_setbit(bi_set_as_si( n, 0), 10)) != 1024) { + puts("!!! bi_setbit set[10] = 1024\n"); + exit(-1); + } + if( bi_get_si( bi_mod_si(bi_tmp, bi_set_as_si( n, 12), 10)) != 2) { + puts("!!! bi_mod_si 12 mod 10 = 2\n"); + exit(-1); + } + if( bi_get_si( bi_mul_si(bi_tmp, bi_set_as_si( n, 12), 10)) != 120) { + puts("!!! bi_mul_si 12 * 10 = 120\n"); + exit(-1); + } + if( bi_get_si( bi_mul(bi_tmp, bi_set_as_si( n, 12), bi_set_as_si( bi_tmp1, 10))) != 120) { + puts("!!! bi_mul_si 12 * 10 = 120\n"); + exit(-1); + } + if( bi_get_si( bi_mod_exp_si(bi_tmp, bi_set_as_si( bi_tmp1, 4), bi_2, 10)) != 6) { + puts("!!! bi_mod_exp_si 4 ^ 2 mod 10 = 6\n"); + exit(-1); + } + if( bi_get_si( bi_mod_exp(bi_tmp, bi_set_as_si( bi_tmp1, 4), bi_2, bi_set_as_si( bi_tmp2, 10))) != 6) { + puts("!!! bi_mod_exp 4 ^ 2 mod 10 = 6\n"); + exit(-1); + } + if( bi_get_si( bi_mod(bi_tmp, bi_set_as_si( n, 12), bi_set_as_si(bi_tmp1, 10))) != 2) { printf("!!! bi_mod 12 mod 10 = 2 [%s]\n",bi_2_dec_char( bi_tmp)); exit(-1); } + if( bi_get_si( bi_mod(bi_tmp, bi_set_as_si( n, -12), bi_set_as_si(bi_tmp1, 10))) != 8) { printf("!!! bi_mod -12 mod 10 = 8 [%s]\n",bi_2_dec_char( bi_tmp)); exit(-1); } + if( bi_get_si( bi_mod(bi_tmp, bi_set_as_si( n, -27), bi_set_as_si(bi_tmp1, 10))) != 3) { printf("!!! bi_mod -27 mod 10 = 3 [%s]\n",bi_2_dec_char( bi_tmp)); exit(-1); } + bi_set_as_si(n, 0x12345678); + bi_2_byte_array( result1, 5, n); + if( result1[0] != 0x00 || result1[1] != 0x12 || result1[2] != 0x34 || result1[3] != 0x56 || result1[4] != 0x78 ) { + printf("!!! bi_2_byte_array[0x123456578] [0]=%x [1]=%x [2]=%x [3]=%x [4]=%x \n", result1[0], result1[1], result1[2], result1[3], result1[4]); + exit( -1); + } + byte_array = retrieve_byte_array( &len, "12345"); + printf("test dump_byte_array len=%d \n", len); + printf("test dump_byte_array(\"12345\")=%s\n", dump_byte_array( len, byte_array)); + free( byte_array); + byte_array = retrieve_byte_array( &len, "12345678"); + printf("test dump_byte_array len=%d \n", len); + printf("test dump_byte_array(\"12345678\")=%s\n", dump_byte_array( len, byte_array)); + + // test save end load of bi_t and bi_array + ///////////////////////////////////////////////////////////////////////////////////// + bi_array result; + bi_new_array( result, 2); + bi_set_as_si( bi_tmp, 6); + bi_set_as_si( result->array[0], 314159); + bi_set_as_si( result->array[1], 123456789); + file = fopen("/tmp/test.todel", "w"); + bi_save_array( result, "result", file); + bi_save( bi_tmp, "bi_tmp", file); + fclose( file); + bi_set_as_si( result->array[0], 0); + bi_set_as_si( result->array[1], 0); + bi_set_as_si( bi_tmp, 0); + file = fopen("/tmp/test.todel", "r"); + bi_load_array( result, file); + bi_load( bi_tmp, file); + fclose( file); + if( bi_get_si( result->array[0]) != 314159) { puts("!!! save/load array[0] = 314159\n"); exit(-1); } + if( bi_get_si( result->array[1]) != 123456789) { puts("!!! save/load array[1] = 123456789\n"); exit(-1); } + if( bi_get_si( bi_tmp) != 6) { puts("!!! save/load bi_tmp = 6\n"); exit(-1); } + + // conversion from bi_t 2 big endian BYTE* + ///////////////////////////////////////////////////////////////////////////////////// + bi_set_as_si( n, 254+(1 << 16)); + buffer = bi_2_nbin( &length, n); + printf("value 2 convert=%s length=%ld\n", bi_2_hex_char( n), bi_nbin_size( n)); + for( i=0; i<length; i++) { + byte = (unsigned char)(buffer[i] & 0xFF); + if( byte != ret[i]) { printf("\n!!! bi_2_nbin[%d] %x = %x\n", i, byte, ret[i]); exit(-1); } + printf("[buffer[%d]=%x]", i, (int)(byte)); + } + printf("\n"); + nn = bi_set_as_nbin( length, buffer); + if( bi_equals_si( nn, 254+(1 << 16) ) == 0) { + printf("\n!!! bi_set_as_nbin %s = %x\n", bi_2_hex_char( nn), 254+(1 << 16)); + exit(-1); + } + if( !bi_equals( bi_sub_si( bi_tmp, bi_set_as_si( bi_tmp1, 9), 1), + bi_mod( bi_tmp2, + bi_mul( bi_tmp3, bi_set_as_si(bi_tmp4, 6), + bi_set_as_si( bi_tmp5, 3)), + bi_set_as_si( bi_tmp6, 10)))) { + puts("!!! 9-1 == (6*3) mod 10\n"); + printf("!!! tmp(8) = %s tmp1(9)=%s tmp2(8)=%s tmp3(6*3)=%s tmp4(6)=%s\ + tmp5(3)=%s tmp6(10)=%s\n", + bi_2_dec_char(bi_tmp), + bi_2_dec_char(bi_tmp1), + bi_2_dec_char(bi_tmp2), + bi_2_dec_char(bi_tmp3), + bi_2_dec_char(bi_tmp4), + bi_2_dec_char(bi_tmp5), + bi_2_dec_char(bi_tmp6)); + exit(-1); + puts("!!! 9-1 == (6*3) mod 10\n"); exit(-1); + } + bi_set_as_si(n, 1); + bi_shift_left(n, n, 10); + printf("1 << 10 = %s\n", bi_2_dec_char( n)); + bi_set_as_si(n, 1); + printf("(1 << 10) >> 5 = %s\n", bi_2_dec_char( bi_shift_right(bi_tmp, bi_shift_left(bi_tmp1, n, 10), 5))); + bi_set_as_si(n, 1); + printf("[* (1 << 10) >> 5 *] = (2^10) / (2^5) -> %s\n", bi_2_dec_char( bi_shift_right( bi_tmp, ( bi_shift_left( bi_tmp1, n, 10)), 5))); + bi_set_as_si( n, 10); + printf(" (2^10) = %s\n", bi_2_dec_char( bi_mod_exp_si( bi_tmp, bi_2, n, 2000))); + printf(" (1<<5) = %s\n", bi_2_dec_char( bi_shift_left( bi_tmp, bi_set_as_si( bi_tmp1, 1), 5))); + printf(" 1024 / 500 = %s\n", bi_2_dec_char( bi_div( bi_tmp, bi_set_as_si( bi_tmp1, 1024), bi_set_as_si( bi_tmp2, 500)))); + printf(" 1024 / 500 = %s\n", bi_2_dec_char( bi_div_si( bi_tmp, bi_set_as_si( bi_tmp1, 1024), 500))); + printf(" (1 << 10) >> 5 = [* (2^10) / (2^5) *] -> %s\n", bi_2_dec_char( bi_div( bi_tmp1, + bi_mod_exp_si( bi_tmp2, bi_2, bi_set_as_si( bi_tmp3, 10), 2000), + bi_mod_exp_si( bi_tmp4, bi_2, bi_set_as_si( bi_tmp5, 5), 2000) ))); + + printf("(1 << 10) >> 5 = (2^10) / (1<<5) -> %d\n", bi_equals( bi_shift_right( bi_tmp, ( bi_shift_left( bi_tmp1, bi_1, 10)), 5), + bi_div( bi_tmp2, + bi_mod_exp_si( bi_tmp3, bi_2, bi_set_as_si( bi_tmp4, 10), 2000), + bi_mod_exp_si( bi_tmp5, bi_2, bi_set_as_si( bi_tmp6, 5), 2000)))); + printf("( 45 ^ -5 ) %% 10 == ( 1 / ( (45 ^ 5) %% 10) ) %% 10\n"); + bi_set_as_si( bi_tmp, 45); + bi_set_as_si( bi_tmp1, 5); + // bi_negate( bi_tmp1); + bi_set_as_si( bi_tmp2, 10); + bi_mod_exp( bi_tmp3, bi_tmp, bi_tmp1, bi_tmp2); + bi_set_as_si( bi_tmp1, 5); + bi_mod_exp( bi_tmp4, bi_tmp, bi_tmp1, bi_tmp2); + printf("\t( 45 ^ -5 ) %% 10 = %s\n", bi_2_dec_char( bi_tmp3)); + printf("\t( 1 / ( (45 ^ 5) %% 10) ) %% 10 = %s\n", bi_2_dec_char( bi_tmp4)); + if( bi_equals( bi_tmp3, bi_tmp4) == 0) { + printf("!!! error !\n"); + exit( -1); + } + for( i=0; i<5; i++) { + bi_generate_prime( bi_tmp, 1024); + printf("bi=%s\n", bi_2_hex_char( bi_tmp)); + printf("bi.length=%ld \n", bi_length( bi_tmp)); + if( bi_length( bi_tmp) != 1024) { puts("!!! length(random(1024)) != 1024\n"); exit(-1); } + } + bi_set_as_si(n, 0); + bi_setbit( n, 10); + printf("setbit(10) = %s\n", bi_2_dec_char( n)); + bi_set_as_dec(n, "123456"); + foo( r, n, 20L); + printf("TEST:%s\n", bi_2_dec_char( r)); + bi_urandom( n, 1024); + bi_urandom( r, 1024); + computeRandomNumber( r, n); + printf("r:%s n:%s\n", bi_2_hex_char( r), bi_2_hex_char( n)); + bi_generate_prime( r, 1024); + printf("prime:%s\nIs probable prime:%d\n", bi_2_hex_char( r), bi_is_probable_prime( r)); + int error = bi_invert_mod( r, r, n); + printf("Invert mod return:%d\nInvert(r):%s\n", error, bi_2_hex_char( r)); + bi_negate( r); + printf("negate(r):%s\n", bi_2_hex_char( r)); + bi_generate_safe_prime( r, 128); + bi_sub_si( n, r, 1); // n= r - 1 + bi_shift_right( n, n, 1); // n = n / 2 + printf("safe prime(r):%s probable_prime:%d\n", bi_2_hex_char( r), bi_is_probable_prime( r)); + printf("safe prime( (r-1)/2):%s probable_prime:%d\n", bi_2_hex_char( n), bi_is_probable_prime( n)); + test_exp_multi(); + bi_free( r); + bi_free( n); + + bi_set_as_si( result->array[0], 1); + printf("result-> 1<<20:%s\n", bi_2_dec_char( bi_shift_left( result->array[0], result->array[0], 20))); + bi_set_as_si( result->array[1], 1); + printf("result1-> 1<<10:%s\n", bi_2_dec_char( bi_shift_right( result->array[1], result->array[0], 10))); + // copy arrays + bi_array new_result; bi_new_array2( new_result, 4); + bi_new_array2( new_result, 4); + bi_copy_array( result, 0, new_result, 0, 2); + bi_copy_array( result, 0, new_result, 2, 2); + for( i = 0; i<4; i++) { + printf("new_result[%d]-> [even-> 1<<20] [odd-> 1<<10] :%s\n", i, bi_2_dec_char( new_result->array[i])); + } + + bi_free( bi_tmp); + bi_free( bi_tmp1); + bi_free( bi_tmp2); + bi_free( bi_tmp3); + bi_free( bi_tmp4); + bi_free( bi_tmp5); + bi_free( bi_tmp6); + bi_release(); + printf("THE END [%s,%s]\n", __DATE__, __TIME__); + fflush(stdout); + return 0; + +} + diff --git a/src/tspi/daa/daa_anonymityrevocation/csencryption_result.c b/src/tspi/daa/daa_anonymityrevocation/csencryption_result.c new file mode 100644 index 0000000..9750e7e --- /dev/null +++ b/src/tspi/daa/daa_anonymityrevocation/csencryption_result.c @@ -0,0 +1,211 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + +#include "daa_parameter.h" +#include "daa_structs.h" +#include "anonymity_revocation.h" +#include "verifier.h" +#include "tsplog.h" + +CS_ENCRYPTION_RESULT *create_CS_ENCRYPTION_RESULT( + bi_ptr c1, + bi_ptr c2, + bi_ptr c3, + bi_ptr c4 +) { + CS_ENCRYPTION_RESULT *result = + (CS_ENCRYPTION_RESULT *)malloc( sizeof(CS_ENCRYPTION_RESULT)); + + if (result == NULL) { + LogError("malloc of %d bytes failed", sizeof(CS_ENCRYPTION_RESULT)); + return NULL; + } + result->c1 = c1; + result->c2 = c2; + result->c3 = c3; + result->c4 = c4; + return result; +} + +CS_ENCRYPTION_RESULT_RANDOMNESS *create_CS_ENCRYPTION_RESULT_RANDOMNESS( + CS_ENCRYPTION_RESULT *cs_encryption_result, + bi_ptr randomness +) { + CS_ENCRYPTION_RESULT_RANDOMNESS *result = + (CS_ENCRYPTION_RESULT_RANDOMNESS *) + malloc(sizeof(CS_ENCRYPTION_RESULT_RANDOMNESS)); + + if (result == NULL) { + LogError("malloc of %d bytes failed", + sizeof(CS_ENCRYPTION_RESULT_RANDOMNESS)); + return NULL; + } + result->randomness = randomness; + result->result = cs_encryption_result; + return result; +} + +bi_ptr compute_u( const EVP_MD *digest, + const bi_ptr c1, + const bi_ptr c2, + const bi_ptr c3, + const BYTE *condition, + const int conditionLength +) { + BYTE *buffer, *bytes; + int c1_size = bi_nbin_size( c1); + int c2_size = bi_nbin_size( c2); + int c3_size = bi_nbin_size( c3); + int index = 0; + int length; + bi_ptr value; + int bufferLength = c1_size + c2_size + c3_size + conditionLength; + + buffer = (BYTE *)malloc( bufferLength); + if (buffer == NULL) { + LogError("malloc of %d bytes failed", bufferLength); + return NULL; + } + bi_2_byte_array( &buffer[index], c1_size, c1); + index += c1_size; + bi_2_byte_array( &buffer[index], c2_size, c2); + index += c2_size; + bi_2_byte_array( &buffer[index], c3_size, c3); + index += c3_size; + memcpy( &buffer[index], condition, conditionLength); + index += conditionLength; + length = DAA_PARAM_LENGTH_MFG1_ANONYMITY_REVOCATION / 8; // 25 /8 + bytes = compute_bytes( bufferLength, buffer, length, digest); + if( bytes == NULL) return NULL; + value = bi_set_as_nbin( length, bytes); + free( bytes); + free( buffer); + return value; +} + +CS_ENCRYPTION_RESULT_RANDOMNESS* internal_compute_encryption_proof( + const bi_ptr msg, + const bi_ptr delta1, + const bi_ptr delta2, + const bi_ptr delta3, + const bi_ptr randomness, + const CS_PUBLIC_KEY *key, + const struct tdTSS_DAA_PK_internal *daa_key, + const BYTE *condition, + const int conditionLength, + const EVP_MD *digest +) { + bi_ptr modulus = daa_key->modulus; + bi_ptr gamma = daa_key->gamma; + bi_ptr c1 = bi_new_ptr( ); + bi_ptr c2 = bi_new_ptr( ); + bi_ptr c3 = bi_new_ptr( ); + bi_ptr c4; + bi_ptr exp; + bi_t bi_tmp; + bi_t bi_tmp1; + + bi_new( bi_tmp); + bi_new( bi_tmp1); + if( bi_cmp( msg, modulus) >= 0) { + LogError("IllegalArgument: msg to big for key size"); + bi_free_ptr( c1); + bi_free_ptr( c2); + bi_free_ptr( c3); + bi_free( bi_tmp); + bi_free( bi_tmp1); + return NULL; + } + bi_mod_exp( c1, gamma, randomness, modulus); + bi_mod_exp( c2, key->eta, randomness, modulus); + // c3=msg * (key->lambda3 ^ randomness) % mopdulus) + bi_mul( c3, msg, bi_mod_exp( bi_tmp, key->lambda3, randomness, modulus)); + bi_mod( c3, c3, modulus); // c3 = c3 % modulus + if( delta1 != NULL) { + if( !( delta2!=NULL && delta3!=NULL)) { + LogError("Illegal Arguments: delta2==NULL or delta3==NULL"); + bi_free_ptr( c1); + bi_free_ptr( c2); + bi_free_ptr( c3); + bi_free( bi_tmp); + bi_free( bi_tmp1); + return NULL; + } + exp = compute_u( digest, delta1, delta2, delta3, condition, conditionLength); + } else { + if( !( delta2==NULL && delta3==NULL)) { + LogError("Illegal Arguments: delta2!=NULL or delta3!=NULL"); + bi_free_ptr( c1); + bi_free_ptr( c2); + bi_free_ptr( c3); + bi_free( bi_tmp); + bi_free( bi_tmp1); + return NULL; + } + exp = compute_u( digest, c1, c2, c3, condition, conditionLength); + } + // exp = exp * randomness + bi_mul( exp, exp, randomness); + // exp = exp % daa_key->rho + bi_mod( exp, exp, daa_key->rho); + // bi_tmp = (key->lambda1 ^ randomness) % modulus + bi_mod_exp( bi_tmp, key->lambda1, randomness, modulus); + // bi_tmp1 = (key->lambda2 ^ exp) % modulus + bi_mod_exp( bi_tmp1, key->lambda2, exp, modulus); + c4 = bi_new_ptr(); + // c4 = bi_tmp * bi_tmp1 + bi_mul( c4, bi_tmp, bi_tmp1); + // c4 = c4 % modulus + bi_mod( c4, c4, modulus); + bi_free_ptr( exp); + bi_free( bi_tmp1); + bi_free( bi_tmp); + return create_CS_ENCRYPTION_RESULT_RANDOMNESS( + create_CS_ENCRYPTION_RESULT( c1, c2, c3, c4), + randomness); +} + +/* +Cramer-Shoup EncryptionProof +from com.ibm.zurich.tcg.daa.anonymityrevocation.CSEncryptionProof + */ +CS_ENCRYPTION_RESULT_RANDOMNESS *compute_ecryption_proof( + const bi_ptr msg, + const bi_ptr delta1, + const bi_ptr delta2, + const bi_ptr delta3, + const bi_ptr randomness, + const CS_PUBLIC_KEY *key, + const struct tdTSS_DAA_PK_internal *daa_key, + const BYTE *condition, + const int conditionLength, + const EVP_MD *digest +) { + if( delta1 == NULL || delta2 == NULL || delta3 == NULL) { + LogError("Illegal Argument: deltas (delta1:%ld delta2:%ld delta3:%ld)", + (long)delta1, (long)delta2, (long)delta3); + return NULL; + } + if( bi_cmp( randomness, daa_key->rho) >=0 || bi_cmp_si( randomness, 0) < 0) { + LogError("randomness >= rho || randomness < 0 \n\trandomness:%s\n\trho:%s\n", + bi_2_dec_char( randomness), bi_2_dec_char( daa_key->rho)); + return NULL; + } + return internal_compute_encryption_proof( msg, + delta1, + delta2, + delta3, + randomness, + key, + daa_key, + condition, + conditionLength, + digest); +} diff --git a/src/tspi/daa/daa_debug.c b/src/tspi/daa/daa_debug.c new file mode 100644 index 0000000..d39273b --- /dev/null +++ b/src/tspi/daa/daa_debug.c @@ -0,0 +1,294 @@ + + +/******************************************************************************************** +* KEY PAIR WITH PROOF +********************************************************************************************/ + +int +save_KEY_PAIR_WITH_PROOF(FILE *file, + KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof) +{ + save_DAA_PK_internal( file, key_pair_with_proof->pk); + save_DAA_PRIVATE_KEY( file, key_pair_with_proof->private_key); + save_DAA_PK_PROOF_internal( file, key_pair_with_proof->proof); + + return 0; +} + +KEY_PAIR_WITH_PROOF_internal * +load_KEY_PAIR_WITH_PROOF(FILE *file) +{ + KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof = + (KEY_PAIR_WITH_PROOF_internal *)malloc(sizeof(KEY_PAIR_WITH_PROOF_internal)); + + key_pair_with_proof->pk = load_DAA_PK_internal(file); + key_pair_with_proof->private_key = load_DAA_PRIVATE_KEY(file); + key_pair_with_proof->proof = load_DAA_PK_PROOF_internal(file); + + return key_pair_with_proof; +} + +int +save_DAA_PK_internal(FILE *file, const TSS_DAA_PK_internal *pk_internal) +{ + char *buffer; + + LogDebug("-> save_DAA_PK_internal"); + + BI_SAVE( pk_internal->modulus, file); + BI_SAVE( pk_internal->capitalS, file); + BI_SAVE( pk_internal->capitalZ, file); + BI_SAVE( pk_internal->capitalR0, file); + BI_SAVE( pk_internal->capitalR1, file); + BI_SAVE( pk_internal->gamma, file); + BI_SAVE( pk_internal->capitalGamma, file); + BI_SAVE( pk_internal->rho, file); + BI_SAVE_ARRAY( pk_internal->capitalRReceiver, file); + BI_SAVE_ARRAY( pk_internal->capitalRIssuer, file); + fprintf( file, "%d\n", pk_internal->issuerBaseNameLength); + buffer = (char *)malloc( pk_internal->issuerBaseNameLength + 1); + memcpy( buffer, pk_internal->issuerBaseName, pk_internal->issuerBaseNameLength); + buffer[ pk_internal->issuerBaseNameLength] = 0; + fprintf( file, "%s\n", buffer); + free( buffer); + + LogDebug("<- save_DAA_PK_internal"); + + return 0; +} + +TSS_DAA_PK_internal * +load_DAA_PK_internal(FILE *file) +{ + TSS_DAA_PK_internal *pk_internal = + (TSS_DAA_PK_internal *)malloc(sizeof(TSS_DAA_PK_internal)); + char *read_buffer; + + pk_internal->modulus = bi_new_ptr(); + BI_LOAD( pk_internal->modulus, file); + pk_internal->capitalS = bi_new_ptr(); + BI_LOAD( pk_internal->capitalS, file); + pk_internal->capitalZ = bi_new_ptr(); + BI_LOAD( pk_internal->capitalZ, file); + pk_internal->capitalR0 = bi_new_ptr(); + BI_LOAD( pk_internal->capitalR0, file); + pk_internal->capitalR1 = bi_new_ptr(); + BI_LOAD( pk_internal->capitalR1, file); + pk_internal->gamma = bi_new_ptr(); + BI_LOAD( pk_internal->gamma, file); + pk_internal->capitalGamma = bi_new_ptr(); + BI_LOAD( pk_internal->capitalGamma, file); + pk_internal->rho = bi_new_ptr(); + BI_LOAD( pk_internal->rho, file); + pk_internal->capitalRReceiver = ALLOC_BI_ARRAY(); + BI_LOAD_ARRAY( pk_internal->capitalRReceiver, file); + pk_internal->capitalRIssuer = ALLOC_BI_ARRAY(); + BI_LOAD_ARRAY( pk_internal->capitalRIssuer, file); + pk_internal->capitalY = ALLOC_BI_ARRAY(); + populate_capitalY( pk_internal); + pk_internal->issuerBaseNameLength = read_int( file); + read_buffer = read_str( file); + pk_internal->issuerBaseName = malloc( pk_internal->issuerBaseNameLength); + memcpy( pk_internal->issuerBaseName, read_buffer, pk_internal->issuerBaseNameLength); + compute_capitalSprime( pk_internal); + return pk_internal; +} + +int +save_DAA_PK_PROOF_internal(FILE *file, TSS_DAA_PK_PROOF_internal *proof) +{ + int i; + +#ifdef DAA_DEBUG + printf("save_DAA_PK_PROOF_internal"); +#endif + fprintf(file, "%d # %s.length\n", proof->length_challenge, "challenge"); + fprintf(file, "%s\n", dump_byte_array( proof->length_challenge, + proof->challenge)); + fprintf(file, "%d # %s.length\n", proof->length_response, "response"); + for (i = 0; i < proof->length_response; i++) { + BI_SAVE_ARRAY( proof->response[i], file); + } + + return 0; +} + +/* load <proof> using <filename> */ +/* allocation of: */ +/* proof->challenge (BYTE*) */ +/* response (bi_array_ptr) */ +TSS_DAA_PK_PROOF_internal * +load_DAA_PK_PROOF_internal(FILE *file) +{ + TSS_DAA_PK_PROOF_internal *proof = + (TSS_DAA_PK_PROOF_internal *)malloc(sizeof(TSS_DAA_PK_PROOF_internal)); + char *read_buffer; + int i; + +#ifdef DAA_DEBUG + printf("load_DAA_PK_PROOF_internal"); +#endif + proof->length_challenge = read_int( file); + read_buffer = read_str( file); + proof->challenge = retrieve_byte_array( &(proof->length_challenge),read_buffer); + proof->length_response = read_int( file); + proof->response = (bi_array_ptr *)malloc( sizeof(bi_array_ptr) * proof->length_response); + for (i = 0; i < proof->length_response; i++) { + proof->response[i] = ALLOC_BI_ARRAY(); + BI_LOAD_ARRAY( proof->response[i], file); + } + return proof; +} + +TSS_DAA_CRED_ISSUER * +load_TSS_DAA_CRED_ISSUER(FILE *file) +{ + TSS_DAA_CRED_ISSUER *credential = + (TSS_DAA_CRED_ISSUER *)malloc(sizeof(TSS_DAA_CRED_ISSUER)); + char *read_buffer; + int i, len; + + init_tss_version( credential); + credential->capitalALength = read_int( file); + read_buffer = read_str( file); + credential->capitalA = retrieve_byte_array( &(credential->capitalALength), + read_buffer); + credential->eLength = read_int( file); + read_buffer = read_str( file); + credential->e = retrieve_byte_array( &(credential->eLength),read_buffer); + credential->vPrimePrimeLength = read_int( file); + read_buffer = read_str( file); + credential->vPrimePrime = retrieve_byte_array(&(credential->vPrimePrimeLength), + read_buffer); + // attributes issuer + credential->attributesIssuerLength = read_int( file); + credential->attributesIssuer = malloc(credential->attributesIssuerLength*sizeof(BYTE*)); + for( i=0; i < (int)credential->attributesIssuerLength; i++) { + credential->attributesIssuer[i] = retrieve_byte_array( &len, read_buffer); + } + credential->cPrimeLength = read_int( file); + read_buffer = read_str( file); + credential->cPrime = retrieve_byte_array( &(credential->cPrimeLength),read_buffer); + credential->sELength = read_int( file); + read_buffer = read_str( file); + credential->sE = retrieve_byte_array( &(credential->sELength),read_buffer); + return credential; +} + +int +save_TSS_DAA_CRED_ISSUER(FILE *file, TSS_DAA_CRED_ISSUER *credential) +{ + int i; + + fprintf(file, "%d # %s.length\n", credential->capitalALength, "capitalA"); + fprintf(file, "%s\n", dump_byte_array( credential->capitalALength, + credential->capitalA)); + fprintf(file, "%d # %s.length\n", credential->eLength, "e"); + fprintf(file, "%s\n", dump_byte_array( credential->eLength, + credential->e)); + fprintf(file, "%d # %s.length\n", credential->vPrimePrimeLength, "vPrimePrime"); + fprintf(file, "%s\n", dump_byte_array( credential->vPrimePrimeLength, + credential->vPrimePrime)); + fprintf(file, "%d # %s\n", credential->attributesIssuerLength, "attributesIssuerLength"); + for( i=0; i < (int)credential->attributesIssuerLength; i++) { + fprintf(file, "%s\n", dump_byte_array( DAA_PARAM_SIZE_F_I / 8, + credential->attributesIssuer[i])); + + } + fprintf(file, "%d # %s.length\n", credential->cPrimeLength, "cPrime"); + fprintf(file, "%s\n", dump_byte_array( credential->cPrimeLength, + credential->cPrime)); + fprintf(file, "%d # %s.length\n", credential->sELength, "sE"); + fprintf(file, "%s\n", dump_byte_array( credential->sELength, + credential->sE)); + return 0; +} + +TSS_DAA_CREDENTIAL * +load_TSS_DAA_CREDENTIAL(FILE *file) +{ + TSS_DAA_CREDENTIAL *credential = + (TSS_DAA_CREDENTIAL *)malloc(sizeof(TSS_DAA_CREDENTIAL)); + char *read_buffer; + int i, len; + TSS_DAA_PK_internal *pk_internal; + TSS_DAA_PK *pk; + + init_tss_version( credential); + credential->capitalALength = read_int( file); + read_buffer = read_str( file); + credential->capitalA = retrieve_byte_array( &(credential->capitalALength), + read_buffer); + credential->exponentLength = read_int( file); + read_buffer = read_str( file); + credential->exponent = retrieve_byte_array( &(credential->exponentLength), + read_buffer); + credential->vBar0Length = read_int( file); + read_buffer = read_str( file); + credential->vBar0 = retrieve_byte_array(&(credential->vBar0Length), + read_buffer); + credential->vBar1Length = read_int( file); + read_buffer = read_str( file); + credential->vBar1 = retrieve_byte_array(&(credential->vBar1Length), + read_buffer); + // attributes issuer + credential->attributesLength = read_int( file); + printf("attributesLength=%d\n", credential->attributesLength); + credential->attributes = malloc(credential->attributesLength * sizeof( BYTE *)); + for( i=0; i < (int)credential->attributesLength; i++) { + read_buffer = read_str( file); + credential->attributes[i] = retrieve_byte_array( &len, read_buffer); + if( len != DAA_PARAM_SIZE_F_I / 8) { + LogError("Error when parsing attributes"); + LogError("\tattribute length:%d", len); + LogError("\texpected length:%d", DAA_PARAM_SIZE_F_I / 8); + return NULL; + } + } + pk_internal = load_DAA_PK_internal( file); + pk = i_2_e_TSS_DAA_PK( pk_internal, &normal_malloc, (TSS_HOBJECT)NULL); + memcpy( &(credential->issuerPK), pk, sizeof(TSS_DAA_PK)); + free( pk); + free_TSS_DAA_PK_internal( pk_internal); + credential->tpmSpecificEncLength = read_int( file); + read_buffer = read_str( file); + credential->tpmSpecificEnc = retrieve_byte_array( &(credential->tpmSpecificEncLength), + read_buffer); + credential->daaCounter = read_int( file); + return credential; +} + +int +save_TSS_DAA_CREDENTIAL(FILE *file, + TSS_DAA_CREDENTIAL *credential) +{ + int i; + TSS_DAA_PK_internal *pk_internal; + + fprintf(file, "%d # %s.length\n", credential->capitalALength, "capitalA"); + fprintf(file, "%s\n", dump_byte_array( credential->capitalALength, + credential->capitalA)); + fprintf(file, "%d # %s.length\n", credential->exponentLength, "exponent"); + fprintf(file, "%s\n", dump_byte_array( credential->exponentLength, + credential->exponent)); + fprintf(file, "%d # %s.length\n", credential->vBar0Length, "vBar0"); + fprintf(file, "%s\n", dump_byte_array( credential->vBar0Length, + credential->vBar0)); + fprintf(file, "%d # %s.length\n", credential->vBar1Length, "vBar1"); + fprintf(file, "%s\n", dump_byte_array( credential->vBar1Length, + credential->vBar1)); + fprintf(file, "%d # %s\n", credential->attributesLength, "attributesLength"); + for( i=0; i < (int)credential->attributesLength; i++) { + fprintf(file, "%s\n", dump_byte_array( DAA_PARAM_SIZE_F_I / 8, + credential->attributes[i])); + } + pk_internal = e_2_i_TSS_DAA_PK( &(credential->issuerPK) ); + save_DAA_PK_internal( file, pk_internal); + free_TSS_DAA_PK_internal( pk_internal); + fprintf(file, "%d # %s.length\n", credential->tpmSpecificEncLength, "tpmSpecificEnc"); + fprintf(file, "%s\n", dump_byte_array( credential->tpmSpecificEncLength, + credential->tpmSpecificEnc)); + fprintf(file, "%d # daaCounter\n", credential->daaCounter); + return 0; +} + diff --git a/src/tspi/daa/daa_debug.h b/src/tspi/daa/daa_debug.h new file mode 100644 index 0000000..368dd3d --- /dev/null +++ b/src/tspi/daa/daa_debug.h @@ -0,0 +1,66 @@ + +/******************************************************************************************** + * KEY PAIR WITH PROOF + ********************************************************************************************/ + +typedef struct tdKEY_PAIR_WITH_PROOF_internal { + TSS_DAA_PK_internal *pk; + DAA_PRIVATE_KEY_internal *private_key; + TSS_DAA_PK_PROOF_internal *proof; +} KEY_PAIR_WITH_PROOF_internal; + +int save_KEY_PAIR_WITH_PROOF( + FILE *file, + KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof +); + +KEY_PAIR_WITH_PROOF_internal *load_KEY_PAIR_WITH_PROOF( + FILE *file +); + +TSS_DAA_KEY_PAIR *get_TSS_DAA_KEY_PAIR( + KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof, + void * (*daa_alloc)(size_t size, TSS_HOBJECT object), + TSS_HOBJECT param_alloc +); + + +int save_DAA_PK_internal( + FILE *file, + const TSS_DAA_PK_internal *pk_internal +); + +TSS_DAA_PK_internal *load_DAA_PK_internal( + FILE *file +); + +int save_DAA_PRIVATE_KEY( + FILE *file, + const DAA_PRIVATE_KEY_internal *private_key +); + +DAA_PRIVATE_KEY_internal *load_DAA_PRIVATE_KEY( + FILE *file +); + +int save_DAA_PK_PROOF_internal( + FILE *file, + TSS_DAA_PK_PROOF_internal *pk_internal +); + +TSS_DAA_PK_PROOF_internal *load_DAA_PK_PROOF_internal( + FILE *file +); + +TSS_DAA_CRED_ISSUER *load_TSS_DAA_CRED_ISSUER( FILE *file); + +int save_TSS_DAA_CRED_ISSUER( FILE *file, TSS_DAA_CRED_ISSUER *credential); + +TSS_DAA_CREDENTIAL *load_TSS_DAA_CREDENTIAL( FILE *file); + +int save_TSS_DAA_CREDENTIAL( + FILE *file, + TSS_DAA_CREDENTIAL *credential +); + + diff --git a/src/tspi/daa/daa_issuer/issue_credential.c b/src/tspi/daa/daa_issuer/issue_credential.c new file mode 100644 index 0000000..0602dcb --- /dev/null +++ b/src/tspi/daa/daa_issuer/issue_credential.c @@ -0,0 +1,787 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +// for message digest +#include <openssl/evp.h> + +#include <stdlib.h> +#include "daa_structs.h" +#include "daa_parameter.h" +#include "trousers/tss.h" +#include "spi_internal_types.h" +#include "spi_utils.h" +#include <trousers/trousers.h> +#include <spi_utils.h> +#include <obj.h> +#include "tsplog.h" +#include "tss/tcs.h" +#include "platform.h" +// to include compute_zeta +#include "verifier.h" + +// from UBigInteger (computePrime) +// remark: the type bi_t (bi_ptr) can not used a certaintity for probable_prime +// as used in UbigInteger. (certaintity: DAA_PARAM_SAFETY) +void compute_prime( bi_ptr e, int length, int interval) { + do { + bi_urandom( e, interval - 1); + bi_setbit( e, length - 1); + } while( bi_is_probable_prime( e) == 0); +} + +/* + code derived from verifyAuthenticity (IssuerTransaction.java) +*/ +TSS_RESULT verify_authentificity(TSS_DAA_CREDENTIAL_REQUEST *credentialRequest, + TSS_DAA_JOIN_ISSUER_SESSION *joinSession) { + EVP_MD_CTX mdctx; + BYTE *modulus_N0_bytes; + BYTE *digest_n0; + BYTE *contextHash; + BYTE *capitalUPrime_bytes; + BYTE *hash; + UINT32 digest_n0Length, contextHashLength, hashLength, daaCount; + bi_ptr capitalUPrime =NULL; + bi_ptr modulus_N0 = NULL; + TSS_RESULT result = TSS_SUCCESS; + char *buffer; + + modulus_N0 = bi_new_ptr(); + buffer = BN_bn2hex( ((RSA *)joinSession->issuerAuthPK)->n); + if( buffer == NULL) { + LogError("malloc of hexadecimal representation failed"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_set_as_hex( modulus_N0, buffer); + // in TPM, N0 is hashed by hashing the scratch (256 bytes) so it must + // be formatted according to the scratch size (TPM_DAA_SIZE_issuerModulus) + modulus_N0_bytes = (BYTE *)malloc( TPM_DAA_SIZE_issuerModulus); + if (modulus_N0_bytes == NULL) { + LogError("malloc of %d bytes failed", TPM_DAA_SIZE_issuerModulus); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_byte_array( modulus_N0_bytes, TPM_DAA_SIZE_issuerModulus, modulus_N0); + bi_free_ptr( modulus_N0); + + if( TPM_DAA_SIZE_issuerModulus * 8 != DAA_PARAM_KEY_SIZE) { + LogError("TPM_DAA_SIZE_issuerModulus * 8 (%d) != DAA_PARAM_KEY_SIZE(%d)", + TPM_DAA_SIZE_issuerModulus*8, DAA_PARAM_KEY_SIZE); + return TSS_E_INTERNAL_ERROR; + } + EVP_DigestInit(&mdctx, DAA_PARAM_get_message_digest()); + // digestN0 = hash( modulus_N0) see Appendix B of spec. and TPM join stage 7 and 8 + EVP_DigestUpdate(&mdctx, modulus_N0_bytes, TPM_DAA_SIZE_issuerModulus); + digest_n0Length = EVP_MD_CTX_size(&mdctx); + digest_n0 = (BYTE *)malloc( digest_n0Length); + if (digest_n0 == NULL) { + LogError("malloc of %d bytes failed", digest_n0Length); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + EVP_DigestFinal(&mdctx, digest_n0, NULL); + + // test if credentialRequest->authenticationProof = + // H( H( U, daaCount, H(n0), joinSession->nonceEncrypted)) + EVP_DigestInit(&mdctx, DAA_PARAM_get_message_digest()); + // enlarge capitalU to 256 (TPM_DAA_SIZE_issuerModulus) + // allocation + capitalUPrime = bi_set_as_nbin( joinSession->capitalUprimeLength, joinSession->capitalUprime); + capitalUPrime_bytes = (BYTE *)malloc( TPM_DAA_SIZE_issuerModulus); + if (capitalUPrime_bytes == NULL) { + LogError("malloc of %d bytes failed", TPM_DAA_SIZE_issuerModulus); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_byte_array( capitalUPrime_bytes, TPM_DAA_SIZE_issuerModulus, capitalUPrime); + EVP_DigestUpdate(&mdctx, capitalUPrime_bytes, TPM_DAA_SIZE_issuerModulus); + bi_free_ptr( capitalUPrime); + daaCount = htonl( joinSession->daaCounter); + EVP_DigestUpdate(&mdctx, &daaCount, sizeof(UINT32)); + EVP_DigestUpdate(&mdctx, digest_n0, digest_n0Length); + contextHashLength = EVP_MD_CTX_size(&mdctx); + contextHash = (BYTE *)malloc( contextHashLength); + if (contextHash == NULL) { + LogError("malloc of %d bytes failed", contextHashLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + EVP_DigestFinal(&mdctx, contextHash, NULL); + EVP_DigestInit(&mdctx, DAA_PARAM_get_message_digest()); + LogDebug("PK(0).n=%s", dump_byte_array( TPM_DAA_SIZE_issuerModulus, modulus_N0_bytes)); + LogDebug("digestN0h=%s", dump_byte_array( digest_n0Length, digest_n0)); + LogDebug("UPrime=%s", dump_byte_array( TPM_DAA_SIZE_issuerModulus, capitalUPrime_bytes)); + LogDebug("daaCount=%4x", daaCount); + + LogDebug("contextHash[%d]=%s", contextHashLength, dump_byte_array( contextHashLength, contextHash)); + EVP_DigestUpdate(&mdctx, contextHash, contextHashLength); + EVP_DigestUpdate(&mdctx, joinSession->nonceEncrypted, joinSession->nonceEncryptedLength); + hashLength = EVP_MD_CTX_size(&mdctx); + hash = (BYTE *)malloc( hashLength); + if (hash == NULL) { + LogError("malloc of %d bytes failed", hashLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + EVP_DigestFinal(&mdctx, hash, NULL); + if( credentialRequest->authenticationProofLength != hashLength || + memcmp( credentialRequest->authenticationProof, hash, hashLength) != 0) { + LogError("Verification of authenticationProof failed - Step 2.b"); + LogError("credentialRequest->authenticationProof[%d]=%s", + credentialRequest->authenticationProofLength, + dump_byte_array( credentialRequest->authenticationProofLength, + credentialRequest->authenticationProof)); + LogError("internal cByte[%d]=%s", + hashLength, + dump_byte_array( hashLength, hash)); + result = TSS_E_DAA_AUTHENTICATION_ERROR; + goto close; + } else + LogDebug("verify_authenticity Done:%s", + dump_byte_array( hashLength, hash)); +close: + free( contextHash); + free( digest_n0); + free( capitalUPrime_bytes); + free( hash); + return result; +} + +TSS_RESULT +compute_join_challenge_issuer( TSS_DAA_PK_internal *pk_intern, + bi_ptr v_prime_prime, + bi_ptr capitalA, + bi_ptr capital_Atilde, + UINT32 nonceReceiverLength, + BYTE *nonceReceiver, + UINT32 *c_primeLength, + BYTE **c_prime) { // out allocation + EVP_MD_CTX mdctx; + BYTE *encoded_pk; + BYTE *byte_array; + UINT32 encoded_pkLength; + + byte_array = (BYTE *)malloc( DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE / 8); // allocation + if (byte_array == NULL) { + LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE / 8); + return TSPERR(TSS_E_OUTOFMEMORY); + } + EVP_DigestInit(&mdctx, DAA_PARAM_get_message_digest()); + encoded_pk = encoded_DAA_PK_internal( &encoded_pkLength, pk_intern); + EVP_DigestUpdate(&mdctx, encoded_pk, encoded_pkLength); + LogDebug( "issuerPk: %s", dump_byte_array( encoded_pkLength, encoded_pk)); + bi_2_byte_array( byte_array, DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE / 8, v_prime_prime); + EVP_DigestUpdate(&mdctx, byte_array, DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE / 8); + LogDebug( "vPrimePrime: %s", + dump_byte_array( DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE / 8, byte_array)); + free( byte_array); + // allocation + byte_array = (BYTE *)malloc( DAA_PARAM_SIZE_RSA_MODULUS / 8); + if (byte_array == NULL) { + LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_RSA_MODULUS / 8); + return TSPERR(TSS_E_OUTOFMEMORY); + } + bi_2_byte_array( byte_array, DAA_PARAM_SIZE_RSA_MODULUS / 8, capitalA); + EVP_DigestUpdate(&mdctx, byte_array, DAA_PARAM_SIZE_RSA_MODULUS / 8); + LogDebug( "capitalA: %s", dump_byte_array( DAA_PARAM_SIZE_RSA_MODULUS / 8, byte_array)); + bi_2_byte_array( byte_array, DAA_PARAM_SIZE_RSA_MODULUS / 8, capital_Atilde); + EVP_DigestUpdate(&mdctx, byte_array, DAA_PARAM_SIZE_RSA_MODULUS / 8); + LogDebug( "capital_Atilde: %s", + dump_byte_array( DAA_PARAM_SIZE_RSA_MODULUS / 8, byte_array)); + EVP_DigestUpdate(&mdctx, nonceReceiver, nonceReceiverLength); + LogDebug( "nonceReceiver: %s", + dump_byte_array( nonceReceiverLength, nonceReceiver)); + *c_primeLength = EVP_MD_CTX_size(&mdctx); + *c_prime = (BYTE *)malloc( *c_primeLength); + if (*c_prime == NULL) { + LogError("malloc of %d bytes failed", *c_primeLength); + free( byte_array); + return TSPERR(TSS_E_OUTOFMEMORY); + } + LogDebug( "c_prime: %s", dump_byte_array( *c_primeLength, *c_prime)); + EVP_DigestFinal(&mdctx, *c_prime, NULL); + free( byte_array); + return TSS_SUCCESS; +} + +// inspired by computeCredentialProof (IssuerTransaction.java) +TSS_RESULT +compute_credential_proof( TSS_DAA_PK_internal *pk_intern, + bi_ptr capital_A, + bi_ptr fraction_A, + bi_ptr eInverse, + bi_ptr v_prime_prime, + bi_ptr productPQprime, + UINT32 noncePlatformLength, + BYTE *noncePlatform, + bi_ptr *c_prime, // out + bi_ptr *s_e // out +) { + bi_ptr random_E = bi_new_ptr(); + bi_ptr capital_Atilde = bi_new_ptr(); + BYTE *c_prime_bytes; + UINT32 c_primeLength; + + bi_urandom( random_E, bi_length( productPQprime) + DAA_PARAM_SAFETY_MARGIN * 8); + bi_mod( random_E, random_E, productPQprime); + bi_inc( random_E); + bi_mod_exp( capital_Atilde, fraction_A, random_E, pk_intern->modulus); + compute_join_challenge_issuer( pk_intern, + v_prime_prime, + capital_A, + capital_Atilde, + noncePlatformLength, + noncePlatform, + &c_primeLength, + &c_prime_bytes); // allocation + *c_prime = bi_set_as_nbin( c_primeLength, c_prime_bytes); // allocation + *s_e = bi_new_ptr(); + bi_mul( *s_e, *c_prime, eInverse); + bi_mod( *s_e, *s_e, productPQprime); + bi_sub( *s_e, random_E, *s_e); + bi_mod( *s_e, *s_e, productPQprime); + bi_free_ptr( capital_Atilde); + bi_free_ptr( random_E); + free( c_prime_bytes); + return TSS_SUCCESS; +} + +// from IssuerTransaction.java (joinStep2) +// stacks: TCGApplication.java (retrieveDAACredential) -> Issuer.java(issueCredential) +TSPICALL Tspi_DAA_IssueCredential_internal +( + TSS_HDAA hDAA, // in + UINT32 attributesIssuerLength, // in + BYTE** attributesIssuer, // in + TSS_DAA_CREDENTIAL_REQUEST credentialRequest, // in + TSS_DAA_JOIN_ISSUER_SESSION joinSession, // in + TSS_DAA_CRED_ISSUER* credIssuer // out +) { + TSS_RESULT result = TSS_SUCCESS; + TCS_CONTEXT_HANDLE tcsContext; + bi_ptr capitalU_hat_prime = NULL; + bi_ptr tmp1; + bi_ptr tmp2; + bi_ptr sa_i; + bi_ptr capitalU_prime = NULL; + bi_ptr c = NULL; + bi_ptr n = NULL; + bi_ptr sf0 = NULL; + bi_ptr sf1 = NULL; + bi_ptr sv_prime = NULL; + bi_ptr capitalR0 = NULL; + bi_ptr capitalR1 = NULL; + bi_ptr capitalS = NULL; + bi_ptr capitalU = NULL; + bi_ptr capitalU_hat = NULL; + bi_ptr capitalN_hat_i = NULL; + bi_ptr exp = NULL; + bi_ptr product_attr_receiver = NULL; + bi_ptr product_attr_issuer = NULL; + bi_ptr sv_tilde_prime = NULL; + bi_ptr capital_ni = NULL; + bi_ptr v_hat = NULL; + bi_ptr fraction_A = NULL; + bi_ptr capitalA = NULL; + bi_ptr e = NULL; + bi_ptr eInverse = NULL; + bi_ptr v_prime_prime = NULL; + bi_ptr c_prime = NULL; + bi_ptr s_e = NULL; + bi_ptr zeta = NULL; + TSS_DAA_PK *daa_pk_extern; + TSS_DAA_PK_internal *pk_intern; + TSS_DAA_PRIVATE_KEY *private_key; + UINT32 i, chLength, challengeLength, length, interval; + EVP_MD_CTX mdctx; + BYTE *ch = NULL, *challenge = NULL; + + tmp1 = bi_new_ptr(); + tmp2 = bi_new_ptr(); + if( tmp1 == NULL || tmp2 == NULL) { + LogError("malloc of BI <%s> failed", "tmp1, tmp2"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + if( (result = obj_daa_get_tsp_context( hDAA, &tcsContext)) != TSS_SUCCESS) goto close; + // 1 TODO Check the TPM rogue list + + // 2 verify the authentication proof of the TPM + result = verify_authentificity(&credentialRequest, &joinSession); + if( result != TSS_SUCCESS) goto close; + daa_pk_extern = (TSS_DAA_PK *)(((TSS_DAA_KEY_PAIR *)joinSession.issuerKeyPair)->public_key); + pk_intern = e_2_i_TSS_DAA_PK( daa_pk_extern); + n = bi_set_as_nbin( daa_pk_extern->modulusLength, + daa_pk_extern->modulus); // allocation + if( n == NULL) { + LogError("malloc of BI <%s> failed", "n"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + capitalR0 = bi_set_as_nbin( daa_pk_extern->capitalR0Length, + daa_pk_extern->capitalR0); // allocation + if( capitalR0 == NULL) { + LogError("malloc of BI <%s> failed", "capitalR0"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + capitalR1 = bi_set_as_nbin( daa_pk_extern->capitalR1Length, + daa_pk_extern->capitalR1); // allocation + if( capitalR1 == NULL) { + LogError("malloc of BI <%s> failed", "capitalR1"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + capitalS = bi_set_as_nbin( daa_pk_extern->capitalSLength, + daa_pk_extern->capitalS); // allocation + if( capitalS == NULL) { + LogError("malloc of BI <%s> failed", "capitalS"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + capitalU = bi_set_as_nbin( credentialRequest.capitalULength, + credentialRequest.capitalU); // allocation + if( capitalU == NULL) { + LogError("malloc of BI <%s> failed", "capitalU"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + sv_tilde_prime = bi_set_as_nbin( credentialRequest.sVtildePrimeLength, + credentialRequest.sVtildePrime); // allocation + if( sv_tilde_prime == NULL) { + LogError("malloc of BI <%s> failed", "sv_tilde_prime"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + capital_ni = bi_set_as_nbin( credentialRequest.capitalNiLength, + credentialRequest.capitalNi); // allocation + if( capital_ni == NULL) { + LogError("malloc of BI <%s> failed", "capital_ni"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + // 3 Verify the correctness proof of the credential request + // 3.a TODO commitments + + // 3.b + capitalU_prime = bi_set_as_nbin( joinSession.capitalUprimeLength, + joinSession.capitalUprime); // allocation + if( capitalU_prime == NULL) { + LogError("malloc of BI <%s> failed", "capitalU_prime"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + sf0 = bi_set_as_nbin( credentialRequest.sF0Length, + credentialRequest.sF0); // allocation + if( sf0 == NULL) { + LogError("malloc of BI <%s> failed", "sf0"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + sf1 = bi_set_as_nbin( credentialRequest.sF1Length, + credentialRequest.sF1); // allocation + if( sf1 == NULL) { + LogError("malloc of BI <%s> failed", "sf1"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + sv_prime = bi_set_as_nbin( credentialRequest.sVprimeLength, + credentialRequest.sVprime); // allocation + if( sv_prime == NULL) { + LogError("malloc of BI <%s> failed", "sv_prime"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + c = bi_set_as_nbin( credentialRequest.challengeLength, + credentialRequest.challenge); // allocation + if( c == NULL) { + LogError("malloc of BI <%s> failed", "c"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + capitalU_hat_prime = bi_new_ptr();// allocation + if( capitalU_hat_prime == NULL) { + LogError("malloc of BI <%s> failed", "c"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + // capitalU_hat_prime = capitalU_prime ~% n + bi_invert_mod( capitalU_hat_prime, capitalU_prime, n); + // capitalU_hat_prime = ( capitalU_hat_prime ^ c ) % n + bi_mod_exp( capitalU_hat_prime, capitalU_hat_prime, c, n); + // capitalU_hat_prime = ( capitalU_hat_prime * ( capitalR0 ^ sf0)) % n + bi_mod_exp( tmp1, capitalR0, sf0, n); + bi_mul( capitalU_hat_prime, capitalU_hat_prime, tmp1); + bi_mod( capitalU_hat_prime, capitalU_hat_prime, n); + // capitalU_hat_prime = ( capitalU_hat_prime * ( capitalR1 ^ sf1)) % n + bi_mod_exp( tmp1, capitalR1, sf1, n); + bi_mul( capitalU_hat_prime, capitalU_hat_prime, tmp1); + bi_mod( capitalU_hat_prime, capitalU_hat_prime, n); + // capitalU_hat_prime = ( capitalU_hat_prime * ( capitalS ^ sv_prime)) % n + bi_mod_exp( tmp1, capitalS, sv_prime, n); + bi_mul( capitalU_hat_prime, capitalU_hat_prime, tmp1); + bi_mod( capitalU_hat_prime, capitalU_hat_prime, n); + // verify blinded encoded attributes of the Receiver + product_attr_receiver = bi_new_ptr(); + bi_set( product_attr_receiver, bi_1); + length = ( DAA_PARAM_SIZE_RANDOMIZED_ATTRIBUTES + 7) / 8; + for( i=0; i<credentialRequest.sALength; i++) { + sa_i = bi_set_as_nbin( length, credentialRequest.sA[i]); // allocation + if( sa_i == NULL) { + LogError("malloc of BI <%s> failed", "sa_i"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_mod_exp( tmp1, pk_intern->capitalRReceiver->array[i], sa_i, n); + bi_mul( product_attr_receiver, product_attr_receiver, tmp1); + bi_mod( product_attr_receiver, product_attr_receiver, n); + bi_free_ptr( sa_i); + } + // tmp1 = ( 1 / capitalU ) % n + bi_invert_mod( tmp1, capitalU, n); + capitalU_hat = bi_new_ptr(); + if( capitalU_hat == NULL) { + LogError("malloc of BI <%s> failed", "capitalU_hat"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_mul( capitalU_hat, capitalU_prime, tmp1); + // capitalU_hat = capitalU_prime / capitalU + bi_mod( capitalU_hat, capitalU_hat, n); + // capital_Uhat = ( (capital_Uhat ^ c ) % n + bi_mod_exp( capitalU_hat, capitalU_hat, c, n); + // capital_Uhat = ( capital_Uhat * ( capitalS ^ sv_tilde_prime) % n ) % n + bi_mod_exp( tmp1, pk_intern->capitalS, sv_tilde_prime, n); + bi_mul( capitalU_hat, capitalU_hat, tmp1); + bi_mod( capitalU_hat, capitalU_hat, n); + bi_mul( capitalU_hat, capitalU_hat, product_attr_receiver); + bi_mod( capitalU_hat, capitalU_hat, n); + // capital_Nhat_i = (( capital_Ni ~% pk_intern->capitalGamma ) ^ c ) % pk_intern->capitalGamma + capitalN_hat_i = bi_new_ptr(); + bi_invert_mod( capitalN_hat_i, capital_ni, pk_intern->capitalGamma); + bi_mod_exp( capitalN_hat_i, capitalN_hat_i, c, pk_intern->capitalGamma); + // exp = sf1 << (DAA_PARAM_SIZE_F_I) + sf0 + exp = bi_new_ptr(); + if( exp == NULL) { + LogError("malloc of BI <%s> failed", "exp"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_shift_left( exp, sf1, DAA_PARAM_SIZE_F_I); + bi_add( exp, exp, sf0); + zeta = compute_zeta( pk_intern->issuerBaseNameLength, + pk_intern->issuerBaseName, + pk_intern); + // capital_Nhat_i = ( capital_Nhat_i * + // ( ( issuer.zeta ^ exp) % pk->capitalGamma) ) % pk->capitalGamma + bi_mod_exp( tmp1, zeta, exp, pk_intern->capitalGamma); + bi_mul( capitalN_hat_i, capitalN_hat_i, tmp1); + bi_mod( capitalN_hat_i, capitalN_hat_i, pk_intern->capitalGamma); + + LogDebug("calculation Uhat: capitalS:%s\n", bi_2_hex_char( pk_intern->capitalS)); + LogDebug("calculation Uhat: sv_tilde_prime:%s\n", bi_2_hex_char( sv_tilde_prime)); + LogDebug("calculation Uhat: n:%s\n", bi_2_hex_char( n)); + LogDebug("calculation Uhat: product_attributes:%s\n", bi_2_hex_char( product_attr_receiver)); + LogDebug("calculation NhatI: zeta:%s\n", bi_2_hex_char( zeta)); + LogDebug("calculation NhatI: exp:%s\n", bi_2_hex_char( exp)); + LogDebug("calculation NhatI: capitalGamma:%s\n", bi_2_hex_char( pk_intern->capitalGamma)); + // calculate challenge + result = compute_join_challenge_host(hDAA, + pk_intern, + capitalU, + capitalU_prime, + capitalU_hat, + capitalU_hat_prime, + capital_ni, + capitalN_hat_i, + 0, // TODO: commitmentsProofLength + NULL, // TODO: commits + joinSession.nonceIssuerLength, + joinSession.nonceIssuer, + &chLength, // out + &ch); // out allocation + if( result != TSS_SUCCESS) goto close; + LogDebug("JoinChallengeHost: %s", dump_byte_array( chLength, ch)); + EVP_DigestInit(&mdctx, DAA_PARAM_get_message_digest()); + EVP_DigestUpdate(&mdctx, ch, chLength); + challengeLength = EVP_MD_CTX_size( &mdctx); + challenge = (BYTE *)malloc( challengeLength); + if( challenge == NULL) { + LogError("malloc of %d bytes failed", challengeLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + EVP_DigestUpdate(&mdctx, credentialRequest.nonceTpm, credentialRequest.nonceTpmLength); + EVP_DigestFinal(&mdctx, challenge, NULL); + // checks + if( credentialRequest.challengeLength != challengeLength || + memcmp( credentialRequest.challenge, challenge, challengeLength)!=0) { + LogError("Verification of c failed - Step 3.f.i"); + LogError("credentialRequest.challenge[%d]=%s", + credentialRequest.challengeLength, + dump_byte_array( credentialRequest.challengeLength, + credentialRequest.challenge)); + LogError("challenge[%d]=%s", + challengeLength, + dump_byte_array( challengeLength, challenge)); + result = TSS_E_DAA_CREDENTIAL_REQUEST_PROOF_ERROR; + goto close; + } + // + 1 because the result of ( rA(43 bits) + c(20 bits) * a(13 bits)) can + // shift 1 bit above the normal size (43 bits) + length = DAA_PARAM_SIZE_RANDOMIZED_ATTRIBUTES + 1; + if( bi_length( sf0) > (long)length) { + LogError( "Verification of sF0 failed - Step 3.f.ii"); + LogError("\tsf0 bits length: %d expected maximum length:%d\n", + (int)bi_length( sf0), (int)length); + result = TSS_E_DAA_CREDENTIAL_REQUEST_PROOF_ERROR; + goto close; + } + if( bi_length( sf1) > (long)length) { + LogError( "Verification of sF1 failed - Step 3.f.ii"); + LogError("\tsf1 length: %d expected maximum length:%d\n", + (int)bi_length( sf1), (int)length); + result = TSS_E_DAA_CREDENTIAL_REQUEST_PROOF_ERROR; + goto close; + } + // blinded attributes + length = DAA_PARAM_SIZE_RANDOMIZED_ATTRIBUTES; + for( i=0; i<credentialRequest.sALength; i++) { + sa_i = bi_set_as_nbin( ( length + 7) / 8, credentialRequest.sA[i]); // allocation + if( sa_i == NULL) { + LogError("malloc of BI <%s> failed", "sa_i"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + if( bi_length( sa_i) > (long)length) { + LogError("Verification of sA[%d] failed - Step 3.f.ii", i); + LogError("sA.length=%d length=%d", (int)bi_length( sa_i), length); + result = TSS_E_DAA_CREDENTIAL_REQUEST_PROOF_ERROR; + goto close; + } + bi_free_ptr( sa_i); + if( result != TSS_SUCCESS) goto close; + } + length = DAA_PARAM_SIZE_RSA_MODULUS + 2 * DAA_PARAM_SAFETY_MARGIN + + DAA_PARAM_SIZE_MESSAGE_DIGEST; + if( bi_length( sv_prime) > (int)length) { + LogError("Verification of sVprime failed - Step 3.f.iii\n"); + LogError("\tsv_prime bits length: %d expected maximum length:%d\n", + (int)bi_length( sv_prime), (int)length); + result = TSS_E_DAA_CREDENTIAL_REQUEST_PROOF_ERROR; + goto close; + } + if( bi_nbin_size( sv_tilde_prime) > (int)length) { + LogError("Verification of sVtildePrime failed - Step 3.f.iii"); + LogError("\tsv_tilde_prime bits length: %d expected maximum length:%d\n", + (int)bi_length( sv_tilde_prime), (int)length); + result = TSS_E_DAA_CREDENTIAL_REQUEST_PROOF_ERROR; + goto close; + } + // compute credential + v_hat = bi_new_ptr(); + if( v_hat == NULL) { + LogError("malloc of BI <%s> failed", "v_hat"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_urandom( v_hat, DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE - 1); + length = DAA_PARAM_SIZE_EXPONENT_CERTIFICATE; + interval = DAA_PARAM_SIZE_INTERVAL_EXPONENT_CERTIFICATE; + e = bi_new_ptr(); + if( e == NULL) { + LogError("malloc of BI <%s> failed", "e"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + compute_prime( e, length, interval); + + // v'' = ( 1 << DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE) + v_hat + v_prime_prime = bi_new_ptr(); + bi_shift_left( tmp1, bi_1, DAA_PARAM_SIZE_RND_VALUE_CERTIFICATE - 1); + bi_add( v_prime_prime, tmp1, v_hat); + + // fraction_A = (( pk->capitalS ^ v``) % n) * capitalU + fraction_A = bi_new_ptr(); + if( fraction_A == NULL) { + LogError("malloc of BI <%s> failed", "fraction_A"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_mod_exp( fraction_A, pk_intern->capitalS, v_prime_prime, n); + bi_mul( fraction_A, fraction_A, capitalU); + bi_mod( fraction_A, fraction_A, n); + + // encode attributes + bi_free_ptr( tmp1); + product_attr_issuer = bi_new_ptr(); + if( product_attr_issuer == NULL) { + LogError("malloc of BI <%s> failed", "product_attr_issuer"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_set( product_attr_issuer, bi_1); + for( i=0; i< attributesIssuerLength; i++) { + tmp1 = bi_set_as_nbin( DAA_PARAM_SIZE_F_I / 8, attributesIssuer[i]); // allocation + bi_mod_exp( tmp2, pk_intern->capitalRIssuer->array[i], tmp1, n); + bi_mul( product_attr_issuer, product_attr_issuer, tmp2); + bi_mod( product_attr_issuer, product_attr_issuer, n); + bi_free_ptr( tmp1); + } + tmp1 = bi_new_ptr(); + if( tmp1 == NULL) { + LogError("malloc of BI <%s> failed", "tmp1"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_mul( fraction_A, fraction_A, product_attr_issuer); + bi_mod( fraction_A, fraction_A, n); + + bi_invert_mod( fraction_A, fraction_A, n); + bi_mul( fraction_A, fraction_A, pk_intern->capitalZ); + bi_mod( fraction_A, fraction_A, n); + + private_key = (TSS_DAA_PRIVATE_KEY *) + (((TSS_DAA_KEY_PAIR *)joinSession.issuerKeyPair)->private_key); + bi_free_ptr( tmp2); + tmp2 = bi_set_as_nbin( private_key->productPQprimeLength, + private_key->productPQprime); // allocation + if( tmp2 == NULL) { + LogError("malloc of BI <%s> failed", "tmp2"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + eInverse = bi_new_ptr(); + if( eInverse == NULL) { + LogError("malloc of BI <%s> failed", "eInverse"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_invert_mod( eInverse, e, tmp2); + capitalA = bi_new_ptr(); + if( capitalA == NULL) { + LogError("malloc of BI <%s> failed", "capitalA"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + LogDebug("fraction_A[%ld]=%s", bi_nbin_size( fraction_A), bi_2_hex_char( fraction_A)); + LogDebug("eInverse[%ld]=%s", bi_nbin_size( eInverse), bi_2_hex_char( eInverse)); + LogDebug("productPQprime[%ld]=%s", bi_nbin_size( tmp2), bi_2_hex_char( tmp2)); + LogDebug("eInverse[%ld]=%s", bi_nbin_size( eInverse), bi_2_hex_char( eInverse)); + LogDebug("e[%ld]=%s", bi_nbin_size( e), bi_2_hex_char( e)); + LogDebug("n[%ld]=%s", bi_nbin_size( n), bi_2_hex_char( n)); + bi_mod_exp( capitalA, fraction_A, eInverse, n); + + compute_credential_proof( pk_intern, + capitalA, + fraction_A, + eInverse, + v_prime_prime, + tmp2, // productPQprime + credentialRequest.noncePlatformLength, + credentialRequest.noncePlatform, + &c_prime, // out: allocation + &s_e); // out: allocation + // populate credIssuer (TSS_DAA_CRED_ISSUER *) + credIssuer->capitalA = calloc_tspi( tcsContext, bi_nbin_size( capitalA)); + if( credIssuer->capitalA == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( capitalA)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(credIssuer->capitalALength), credIssuer->capitalA, capitalA); + credIssuer->e = calloc_tspi( tcsContext, bi_nbin_size( e)); + if( credIssuer->e == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( e)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(credIssuer->eLength), credIssuer->e, e); + credIssuer->vPrimePrime = calloc_tspi( tcsContext, bi_nbin_size( v_prime_prime)); + if( credIssuer->vPrimePrime == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( v_prime_prime)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(credIssuer->vPrimePrimeLength), credIssuer->vPrimePrime, v_prime_prime); + // attributes issuer + credIssuer->attributesIssuerLength = attributesIssuerLength; + credIssuer->attributesIssuer = calloc_tspi( tcsContext, + attributesIssuerLength * sizeof( BYTE *)); + if( credIssuer->attributesIssuer == NULL) { + LogError("malloc of %d bytes failed", attributesIssuerLength * sizeof( BYTE *)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + for( i=0; i< attributesIssuerLength; i++) { + credIssuer->attributesIssuer[i] = calloc_tspi( tcsContext, DAA_PARAM_SIZE_F_I / 8); + if( credIssuer->attributesIssuer[i] == NULL) { + LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_F_I / 8); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + memcpy( credIssuer->attributesIssuer[i], attributesIssuer[i], DAA_PARAM_SIZE_F_I / 8); + } + credIssuer->cPrime = calloc_tspi( tcsContext, bi_nbin_size( c_prime)); + if( credIssuer->cPrime == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( c_prime)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(credIssuer->cPrimeLength), credIssuer->cPrime, c_prime); + credIssuer->sE = calloc_tspi( tcsContext, bi_nbin_size( s_e)); + if( credIssuer->sE == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( s_e)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(credIssuer->sELength), credIssuer->sE, s_e); + +close: + //free_TSS_DAA_PK( daa_pk_extern); + if( ch != NULL) free( ch); + if( challenge != NULL) free( challenge); + FREE_BI( tmp1); + FREE_BI( tmp2); + FREE_BI( s_e); + FREE_BI( c_prime); + FREE_BI( capitalA); + FREE_BI( v_prime_prime); + FREE_BI( eInverse); + FREE_BI( e); + FREE_BI( fraction_A); + FREE_BI( v_hat); + FREE_BI( capital_ni); + FREE_BI( sv_tilde_prime); + FREE_BI( product_attr_receiver); + FREE_BI( product_attr_issuer); + FREE_BI( capitalU_hat_prime); + FREE_BI( capitalU_prime); + FREE_BI( sv_prime); + FREE_BI( exp); + FREE_BI( capitalN_hat_i); + FREE_BI( capitalU_hat); + FREE_BI( capitalU); + FREE_BI( capitalS); + FREE_BI( capitalR1); + FREE_BI( capitalR0); + FREE_BI( sf1); + FREE_BI( sf0); + FREE_BI( n); + FREE_BI( c); + FREE_BI( zeta); + return result; +} diff --git a/src/tspi/daa/daa_issuer/issuer_init.c b/src/tspi/daa/daa_issuer/issuer_init.c new file mode 100644 index 0000000..788bb8d --- /dev/null +++ b/src/tspi/daa/daa_issuer/issuer_init.c @@ -0,0 +1,142 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +// for message digest +#include <openssl/evp.h> + +#include <stdlib.h> +#include "daa_structs.h" +#include "daa_parameter.h" +#include "trousers/tss.h" +#include "spi_internal_types.h" +#include "spi_utils.h" +#include <trousers/trousers.h> +#include <spi_utils.h> +#include <obj.h> +#include "tsplog.h" +#include "tss/tcs.h" + +/* +Verifies if the key is a valid endorsement key of a TPM. (TPM is good) +return 0 if correct + */ +int verify_ek_and_daaCounter( + UINT32 endorsementLength, + BYTE *endorsementCredential, + UINT32 daaCounter +) { + // TODO + return 0; +} + + +TSS_RESULT Tspi_DAA_IssueInit_internal( + TSS_HDAA hDAA, // in + TSS_HKEY issuerAuthPK, // in + TSS_HKEY issuerKeyPair, // in (TSS_DAA_KEY_PAIR *) + TSS_DAA_IDENTITY_PROOF identityProof, // in + UINT32 capitalUprimeLength, // in + BYTE* capitalUprime, // in + UINT32 daaCounter, // in + UINT32* nonceIssuerLength, // out + BYTE** nonceIssuer, // out + UINT32* authenticationChallengeLength, // out + BYTE** authenticationChallenge, // out + TSS_DAA_JOIN_ISSUER_SESSION* joinSession // out +) { + TCS_CONTEXT_HANDLE tcsContext; + TSS_RESULT result; + BYTE *ne, *buffer; + bi_t random; + int length_ne; + + if( (result = obj_daa_get_tsp_context( hDAA, &tcsContext)) != TSS_SUCCESS) + return result; + // 1 & 2 : verify EK (and associated credentials) of the platform + if( verify_ek_and_daaCounter( identityProof.endorsementLength, + identityProof.endorsementCredential, daaCounter) != 0) { + LogError("EK verification failed"); + return TSS_E_INTERNAL_ERROR; + } + + // 3 : choose a random nonce for the platform (ni) + bi_new( random); + bi_urandom( random, DAA_PARAM_LENGTH_MESSAGE_DIGEST * 8); + buffer = bi_2_nbin( nonceIssuerLength, random); + if( buffer == NULL) { + LogError("malloc of %d bytes failed", *nonceIssuerLength); + return TSPERR(TSS_E_OUTOFMEMORY); + } + *nonceIssuer = convert_alloc( tcsContext, *nonceIssuerLength, buffer); + if (*nonceIssuer == NULL) { + LogError("malloc of %d bytes failed", *nonceIssuerLength); + free( buffer); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + LogDebug("nonce Issuer[%d:%d]:%s", DAA_PARAM_LENGTH_MESSAGE_DIGEST, + *nonceIssuerLength, + dump_byte_array( *nonceIssuerLength , *nonceIssuer)); + + // 4 : choose a random nonce ne and encrypt it under EK + bi_urandom( random, DAA_PARAM_LENGTH_MESSAGE_DIGEST * 8); + ne = convert_alloc( tcsContext, length_ne, bi_2_nbin( &length_ne, random)); + if (ne == NULL) { + LogError("malloc of %d bytes failed", length_ne); + free( buffer); + free( nonceIssuer); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + bi_free( random); + *authenticationChallenge = (BYTE *)calloc_tspi( tcsContext, 256); // 256: RSA size + if (*authenticationChallenge == NULL) { + LogError("malloc of %d bytes failed", 256); + free( buffer); + free( nonceIssuer); + free( ne); + return TSPERR(TSS_E_OUTOFMEMORY); + } + result = Trspi_RSA_Encrypt( + ne, // message to encrypt + length_ne, // length message to encrypt + *authenticationChallenge, // destination + authenticationChallengeLength, // length destination + identityProof.endorsementCredential, // public key + identityProof.endorsementLength); // public key size + if( result != TSS_SUCCESS) { + LogError("Can not encrypt the Authentication Challenge"); + free( buffer); + free( nonceIssuer); + free( ne); + return TSS_E_INTERNAL_ERROR; + } + LogDebug("authenticationChallenge[%d:%d]:%s", DAA_PARAM_LENGTH_MESSAGE_DIGEST, + *authenticationChallengeLength, + dump_byte_array( *authenticationChallengeLength , *authenticationChallenge)); + + // 5 : save PK, PKDAA, (p', q'), U', daaCounter, ni, ne in joinSession + // EK is not a member of joinSession but is already saved in identityProof + joinSession->issuerAuthPK = issuerAuthPK; + joinSession->issuerKeyPair = issuerKeyPair; + memcpy( &(joinSession->identityProof), &identityProof, sizeof(TSS_DAA_IDENTITY_PROOF)); + joinSession->capitalUprimeLength = capitalUprimeLength; + joinSession->capitalUprime = capitalUprime; + joinSession->daaCounter = daaCounter; + joinSession->nonceIssuerLength = *nonceIssuerLength; + joinSession->nonceIssuer = *nonceIssuer; + joinSession->nonceEncryptedLength = length_ne; + joinSession->nonceEncrypted = ne; + return result; +} diff --git a/src/tspi/daa/daa_issuer/issuer_setup.c b/src/tspi/daa/daa_issuer/issuer_setup.c new file mode 100644 index 0000000..44e3679 --- /dev/null +++ b/src/tspi/daa/daa_issuer/issuer_setup.c @@ -0,0 +1,166 @@ +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#include "trousers/tss.h" +#include "spi_internal_types.h" +#include "spi_utils.h" +#include "obj.h" +// #include "tcslog.h" +#include "bi.h" +#include "daa_parameter.h" +#include "issuer.h" + +static char *DEFAULT_FILENAME = "issuer.txt"; +static char *DEFAULT_ISSUER = "IBM-Issuer"; + +static const int DEFAULT_ISSUER_ATTRIBUTES = 2; // A1 A2 +static const int DEFAULT_RECEIVER_ATTRIBUTES = 3; // A3 A4 A5 + +int print_usage(char *cmd) { + fprintf(stderr, "usage: %s\n", cmd); + fprintf(stderr, " \t-npa,\t--nb_platform_attr\tnumber of attributes that the\ + Platform can choose and which will not be visible to the Issuer (default: %d)\n", + DEFAULT_ISSUER_ATTRIBUTES); + fprintf(stderr, " \t-nia,\t--nb_issuer_attr\tnumber of attributes that the issuer\ + can choose and which will be visible to both the Platform and the Issuer(default: %d)\n", + DEFAULT_RECEIVER_ATTRIBUTES); + fprintf(stderr, " \t-if,\t--issuer_file\tthe file that will contain all key pair\ + and proof to be used by the issuer (default: %s)\n", + DEFAULT_FILENAME); + fprintf(stderr, " \t-i,\t--issuer\tissuer identity (default: %s)\n", + DEFAULT_ISSUER); + return -1; +} + +int main(int argc, char *argv[]) { + int nb_platform_attr = DEFAULT_ISSUER_ATTRIBUTES; + int nb_issuer_attr = DEFAULT_RECEIVER_ATTRIBUTES; + char *filename = DEFAULT_FILENAME; + char *issuer = DEFAULT_ISSUER; + int i; + char *param; + TSS_HCONTEXT hContext; + TSS_DAA_KEY_PAIR *key_pair; + TSS_DAA_PK_PROOF *public_keyproof; + TSS_RESULT result; + TSS_HDAA hDAA; + TSS_DAA_PK_PROOF_internal *public_keyproof_internal; + TSS_DAA_PK_internal *pk; + TSS_DAA_PRIVATE_KEY *private_key; + DAA_PRIVATE_KEY_internal *private_key_internal; + KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof; + + printf("Issuer Setup (%s:%s,%s)\n", argv[0], __DATE__, __TIME__); + i = 1; + while( i < argc) { + param = argv[ i]; + if ( strcmp( param, "-if") == 0 || strcmp( param, "--issuer_file")) { + i++; + if( i == argc) return print_usage( argv[0]); + filename = argv[i]; + } else if( strcmp( param, "-npa") == 0 || strcmp( param, "--nb_platform_attr")) { + i++; + if( i == argc) return print_usage( argv[0]); + nb_platform_attr = atoi( argv[i]); + } else if( strcmp( param, "-nia") == 0 || strcmp( param, "--nb_issuer_attr")) { + i++; + if( i == argc) return print_usage( argv[0]); + nb_issuer_attr = atoi(argv[i]); + } else if( strcmp( param, "-i") == 0 || strcmp( param, "--issuer")) { + i++; + if( i == argc) return print_usage( argv[0]); + issuer = argv[i]; + } else { + fprintf(stderr, "%s:unrecognized option `%s'\n", argv[0], param); + return print_usage( argv[0]); + } + i++; + } + bi_init( NULL); + // Create Context + printf("Create Context\n"); + result = Tspi_Context_Create( &hContext ); + if ( result != TSS_SUCCESS ) + { + fprintf( stderr, "Tspi_Context_Create %d\n", result ); + exit( result ); + } + + // Connect to Context + printf("Connect to the context\n"); + result = Tspi_Context_Connect( hContext, NULL ); + if ( result != TSS_SUCCESS ) + { + fprintf( stderr, "Tspi_Context_Connect error:%d\n", result ); + Tspi_Context_FreeMemory( hContext, NULL ); + Tspi_Context_Close( hContext ); + exit( result ); + } + //Create Object + result = obj_daa_add( hContext, &hDAA); + if (result != TSS_SUCCESS) { + goto close; + } + result = Tspi_DAA_IssueSetup( + hDAA, // in + strlen( issuer), // in + (BYTE *)issuer, // in + nb_platform_attr, // in + nb_issuer_attr, // in + (TSS_HKEY *)&key_pair, // out + &public_keyproof); // out + if( result != TSS_SUCCESS) goto close; + + // TSS_DAA_KEY_PAIR_internal *key_pair_internal = DAA_KEY_PAIR_2_internal( key_pair); + public_keyproof_internal = e_2_i_TSS_DAA_PK_PROOF( public_keyproof); + pk = e_2_i_TSS_DAA_PK( key_pair->public_key); + private_key = key_pair->private_key; + private_key_internal = e_2_i_TSS_DAA_PRIVATE_KEY( private_key); + key_pair_with_proof = + (KEY_PAIR_WITH_PROOF_internal *)malloc( sizeof(KEY_PAIR_WITH_PROOF_internal)); + if( key_pair_with_proof == NULL) { + fprintf("malloc of %d bytes failed", sizeof(KEY_PAIR_WITH_PROOF_internal)); + goto close; + } + key_pair_with_proof->pk = pk; + key_pair_with_proof->private_key = private_key_internal; + key_pair_with_proof->proof = public_keyproof_internal; + + printf("Saving key pair with proof -> \'%s\'", filename); + FILE *file = fopen( filename, "w"); + if( file == NULL) { + fprintf( stderr, "%s: Error when saving \'%s\': %s\n", + argv[0], + filename, + strerror( errno)); + return -1; + } + if( save_KEY_PAIR_WITH_PROOF( file, key_pair_with_proof) != 0) { + fprintf( stderr, "%s: Error when saving \'%s\': %s\n", + argv[0], + filename, + strerror( errno)); + return -1; + } + fclose( file); + printf("\nDone.\n"); +close: + obj_daa_remove( hDAA, hContext); + printf("Closing the context\n"); + Tspi_Context_FreeMemory( hContext, NULL ); + Tspi_Context_Close( hContext ); + bi_release(); + printf("Result: %d", result); + return result; +} diff --git a/src/tspi/daa/daa_issuer/key_correctness_proof.c b/src/tspi/daa/daa_issuer/key_correctness_proof.c new file mode 100644 index 0000000..505e760 --- /dev/null +++ b/src/tspi/daa/daa_issuer/key_correctness_proof.c @@ -0,0 +1,516 @@ +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +// for little-big endian conversion +#include <arpa/inet.h> +// for message digest +#include <openssl/evp.h> + +#include "bi.h" + +#include "daa_parameter.h" +#include "list.h" +#include "daa_structs.h" + +#include "issuer.h" + +//standard bit length extension to obtain a uniformly distributed number [0,element] +static const int SAFETY_PARAM = 80; + +static bi_array_ptr get_generators( const TSS_DAA_PK_internal *pk) { + bi_array_ptr result = ALLOC_BI_ARRAY(); + int i; + + bi_new_array( result, 3 + pk->capitalY->length ); + for(i = 0; i<result->length; i++) { + result->array[i] = pk->capitalS; + } + return result; +} + +static bi_array_ptr get_verifiable_numbers( const TSS_DAA_PK_internal *pk) { + bi_array_ptr result = ALLOC_BI_ARRAY(); + int i; + + bi_new_array( result, 3 + pk->capitalY->length); + result->array[0] = pk->capitalZ; + result->array[1] = pk->capitalR0; + result->array[2] = pk->capitalR1; + // CAPITAL Y ( capitalRReceiver + capitalRIssuer) + for( i=0; i<pk->capitalY ->length; i++) + result->array[ 3+i] = pk->capitalY->array[i]; + return result; +} + +/* computes an array of random numbers in the range of [1,element] */ +void compute_random_numbers( bi_array_ptr result, int quantity, const bi_ptr element) { + int i=0; + + for( i=0; i<quantity; i++) { + compute_random_number( result->array[i], element); + bi_inc( result->array[i]); // array[i]++ + } +} + +int test_bit( int pos, BYTE* array, int length) { + return (((int)array[ length - (pos / 8) - 1]) & (1 << (pos % 8))) != 0; +} + +void toByteArray( BYTE *result, int length, bi_ptr bi, char *logMsg) { + LogDebug("-> toByteArray <%d> %s",(int)bi, logMsg); + LogDebug("lenghts <%d|%d>",length, (int)bi_nbin_size(bi)); + bi_2_byte_array( result, length, bi); + LogDebug("<- toByteArray result=%s [<%d|%d>] ", + dump_byte_array( length, result), + length, + (int)bi_nbin_size(bi)); +} + +/* +Compute the message digest used in the proof. (from DAA_Param, the digest +algorithm is RSA, but this is not available in openssl, the successor of RSA is SHA1 +*/ +TSS_RESULT +generateMessageDigest(BYTE *md_value, + int *md_len, + const TSS_DAA_PK_internal *pk, + bi_array_ptr *commitments, + const int commitments_size +) { + EVP_MD_CTX mdctx; + const EVP_MD *md; + int i, j; + int length = DAA_PARAM_SIZE_RSA_MODULUS / 8; + BYTE *array; + + // 10000 to be sure, and this memory will be released quite quickly + array = (BYTE *)malloc( 10000); + if (array == NULL) { + LogError("malloc of %d bytes failed", 10000); + return TSPERR(TSS_E_OUTOFMEMORY); + } + OpenSSL_add_all_digests(); + md = EVP_get_digestbyname( DAA_PARAM_MESSAGE_DIGEST_ALGORITHM); + EVP_MD_CTX_init(&mdctx); + EVP_DigestInit_ex(&mdctx, md, NULL); +#ifdef DAA_DEBUG + fprintf(stderr, "modulus=%s\n", bi_2_hex_char( pk->modulus)); +#endif + toByteArray( array, length, pk->modulus, + "!! [generateMessageDigest modulus] current_size=%d length=%d\n"); + EVP_DigestUpdate(&mdctx, array , length); + toByteArray( array, length, pk->capitalS, + "!! [generateMessageDigest capitalS] current_size=%d length=%d\n"); + EVP_DigestUpdate(&mdctx, array , length); + // add capitalZ, capitalR0, capitalR1, capitalY + LogDebug("capitalZ capitalR0 capitalY"); + toByteArray( array, length, pk->capitalZ, + "!! [generateMessageDigest capitalZ] current_size=%d length=%d\n"); + EVP_DigestUpdate(&mdctx, array , length); + toByteArray( array, length, pk->capitalR0, + "!! [generateMessageDigest capitalR0] current_size=%d length=%d\n"); + EVP_DigestUpdate(&mdctx, array , length); + toByteArray( array, length, pk->capitalR1, + "!! [generateMessageDigest capitalR1] current_size=%d length=%d\n"); + EVP_DigestUpdate(&mdctx, array , length); + // CAPITAL Y ( capitalRReceiver ) + LogDebug("capitalRReceiver"); + for( i=0; i<pk->capitalRReceiver->length; i++) { + toByteArray( array, length, pk->capitalRReceiver->array[i], + "!![generateMessageDigest capitalRReceiver] current_size=%d length=%d\n"); + EVP_DigestUpdate(&mdctx, array , length); + } + LogDebug("capitalRIssuer"); + // CAPITAL Y ( capitalRIssuer) + for( i=0; i<pk->capitalRIssuer->length; i++) { + toByteArray( array, length, pk->capitalRIssuer->array[i], + "!![generateMessageDigest capitalRReceiver] current_size=%d length=%d\n"); + EVP_DigestUpdate(&mdctx, array , length); + } + LogDebug("commitments"); + for( i=0; i<commitments_size; i++) { + for( j=0; j<commitments[i]->length; j++) { + toByteArray( array, length, commitments[i]->array[j], + "!! [generateMessageDigest commitments] current_size=%d length=%d\n"); + EVP_DigestUpdate(&mdctx, array , length); + } + } + EVP_DigestFinal_ex(&mdctx, md_value, md_len); + EVP_MD_CTX_cleanup(&mdctx); + free( array); + return TSS_SUCCESS; +} + +int is_range_correct( bi_ptr b, bi_ptr range) { + return bi_cmp( b, range) < 0 && bi_cmp( b, bi_0) >= 0; +} + +/* +Verifies if the parameters Z,R0,R1,RReceiver and RIssuer of the public key +were correctly computed. +pk: the public key, which one wants to verfy. +*/ +TSS_RESULT +is_pk_correct( TSS_DAA_PK_internal *public_key, + TSS_DAA_PK_PROOF_internal *proof, + int *isCorrect +) { + int bit_size_message_digest = DAA_PARAM_SIZE_MESSAGE_DIGEST; + bi_ptr n = public_key->modulus; + int num_of_variables; + int i,j; + TSS_RESULT result = TSS_SUCCESS; + BYTE verifiable_challenge[EVP_MAX_MD_SIZE]; + int length_challenge; + bi_array_ptr verifiable_numbers; + bi_array_ptr *verification_commitments = NULL; + bi_array_ptr generators = NULL; + bi_t tmp; + bi_t tmp1; +#ifdef DAA_DEBUG + FILE *f; + bi_array_ptr *commitments; +#endif + + bi_new( tmp); + bi_new( tmp1); + *isCorrect = 0; +#ifdef DAA_DEBUG + f=fopen("/tmp/commits", "r"); + commitments = (bi_array_ptr *)malloc( sizeof(bi_array_ptr) * num_of_variables); + if (commitments == NULL) { + LogError("malloc of %d bytes failed", sizeof(bi_array_ptr) * num_of_variables); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + for( i=0; i<num_of_variables; i++) { + commitments[i] = ALLOC_BI_ARRAY(); + BI_LOAD_ARRAY( commitments[i], f); + } + fclose(f); + DUMP_BI( n); +#endif + LogDebug("STEP 1 ( Tspi_DAA_IssuerKeyVerification spec.)"); + if( !bi_is_probable_prime( public_key->capitalGamma)) { + LogError( "pk->capitalGamma not prime\ncapitalGamma=\n%s", + bi_2_hex_char( public_key->capitalGamma)); + result = TSS_E_BAD_PARAMETER; + goto close; + } + if( !bi_is_probable_prime( public_key->rho)) { + LogError( "pk->rho not prime\nrho=\n%s", + bi_2_hex_char( public_key->rho)); + result = TSS_E_BAD_PARAMETER; + goto close; + } + // (capitalGamma - 1) % rho should be equal to 0 + if( !bi_equals( bi_mod( tmp1, bi_sub( tmp1, public_key->capitalGamma, bi_1), + public_key->rho), + bi_0)) { + LogError( "(capitalGamma - 1) %% rho != 0\nActual value:\n%s", + bi_2_hex_char( tmp1)); + result = TSS_E_BAD_PARAMETER; + } + // (gamma ^ rho) % capitalGamma should be equals to 1 + if ( !bi_equals( bi_mod_exp( tmp1, public_key->gamma, + public_key->rho, + public_key->capitalGamma), + bi_1) ) { + LogError( "(gamma ^ rho) %% capitalGamma != 1\nActual value:\n%s", + bi_2_hex_char( tmp1)); + result = TSS_E_BAD_PARAMETER; + goto close; + } + // (gamma ^ rho) % capitalGamma should be equal to 1 + if ( !bi_equals( bi_mod_exp( tmp1, + public_key->gamma, + public_key->rho, + public_key->capitalGamma), + bi_1) ) { + LogError( "(gamma ^ rho) %% capitalGamma != 1\nActual value:\n%s", + bi_2_hex_char( tmp1)); + result = TSS_E_BAD_PARAMETER; + goto close; + } + LogDebug("STEP 2 check whether all public key parameters have the required length"); + if( bi_nbin_size( n) != DAA_PARAM_SIZE_RSA_MODULUS / 8) { + LogError( "size( n)[%ld] != DAA_PARAM_SIZE_RSA_MODULUS[%d]", + bi_nbin_size( n), + DAA_PARAM_SIZE_RSA_MODULUS / 8); + result = TSS_E_BAD_PARAMETER; + goto close; + } + if( bi_cmp( n, bi_shift_left( tmp1, bi_1, DAA_PARAM_SIZE_RSA_MODULUS)) + >= 0) { + LogError( "n[%ld] != DAA_PARAM_SIZE_RSA_MODULUS[%d]", + bi_nbin_size( n), + DAA_PARAM_SIZE_RSA_MODULUS); + result = TSS_E_BAD_PARAMETER; + goto close; + } + if( bi_cmp( n, bi_shift_left( tmp1, bi_1, DAA_PARAM_SIZE_RSA_MODULUS - 1 )) + <= 0) { + LogError( "n[%ld] != DAA_PARAM_SIZE_RSA_MODULUS[%d]", + bi_nbin_size( n), + DAA_PARAM_SIZE_RSA_MODULUS); + result = TSS_E_BAD_PARAMETER; + goto close; + } + // rho + if( bi_nbin_size( public_key->rho) * 8 != DAA_PARAM_SIZE_RHO) { + LogError( "size( rho)[%ld] != DAA_PARAM_SIZE_RHO[%d]", + bi_nbin_size( public_key->rho) * 8, + DAA_PARAM_SIZE_RHO); + result = TSS_E_BAD_PARAMETER; + goto close; + } + // Gamma + if( bi_nbin_size( public_key->capitalGamma) * 8 != DAA_PARAM_SIZE_MODULUS_GAMMA) { + LogError( "size( rho)[%ld] != DAA_PARAM_SIZE_MODULUS_GAMMA[%d]", + bi_nbin_size( public_key->capitalGamma) * 8, + DAA_PARAM_SIZE_MODULUS_GAMMA); + result = TSS_E_BAD_PARAMETER; + goto close; + } + if( is_range_correct( public_key->capitalS, n) == 0) { + LogError( "range not correct( pk->capitalS)\ncapitalS=\n%s\nn=\n%s", + bi_2_hex_char( public_key->capitalS), + bi_2_hex_char( n)); + result = TSS_E_BAD_PARAMETER; + goto close; + } + if( is_range_correct( public_key->capitalZ, n) == 0) { + LogError( "range not correct( pk->capitalZ)\ncapitalZ=\n%s\nn=\n%s", + bi_2_hex_char( public_key->capitalZ), + bi_2_hex_char( n)); + result = TSS_E_BAD_PARAMETER; + goto close; + } + if( is_range_correct( public_key->capitalR0, n) == 0) { + LogError( "range not correct( pk->capitalR0)\ncapitalR0=\n%s\nn=\n%s", + bi_2_hex_char( public_key->capitalR0), + bi_2_hex_char( n)); + result = TSS_E_BAD_PARAMETER; + goto close; + } + if( is_range_correct( public_key->capitalR1, n) == 0) { + LogError( "range not correct( pk->capitalR1)\ncapitalR1=\n%s\nn=\n%s", + bi_2_hex_char( public_key->capitalR1), + bi_2_hex_char( n)); + result = TSS_E_BAD_PARAMETER; + goto close; + } + for( i=0; i<public_key->capitalY->length; i++) { + if( is_range_correct( public_key->capitalY->array[i], n) == 0) { + LogError( "range not correct(pk->capitalY[%d])\ncapitalY[%d]=\n%s\nn=\n%s", + i, i, + bi_2_hex_char( public_key->capitalY->array[i]), + bi_2_hex_char( n)); + result = TSS_E_BAD_PARAMETER; + goto close; + } + } + LogDebug("STEP 3 - compute verification commitments"); + // only the array is allocated, but all refs are pointing to public_key numbers + generators = get_generators( public_key); + verifiable_numbers = get_verifiable_numbers( public_key); + num_of_variables = verifiable_numbers->length; + verification_commitments = (bi_array_ptr *)malloc( sizeof(bi_array_ptr)*num_of_variables); + if (verification_commitments == NULL) { + LogError("malloc of %d bytes failed", sizeof(bi_array_ptr)*num_of_variables); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + for( i = 0; i<num_of_variables; i++) { + verification_commitments[i] = ALLOC_BI_ARRAY(); + bi_new_array( verification_commitments[i], bit_size_message_digest); + for( j = 0; j<bit_size_message_digest; j++) { +#ifdef DAA_DEBUG + printf( "[# i=%d j=%d test_bit:%d]", + i, j, test_bit( j, proof->challenge, proof->length_challenge)); +#endif + bi_mod_exp( verification_commitments[i]->array[j], + generators->array[i], + proof->response[i]->array[j], n); + if( test_bit( j, proof->challenge, proof->length_challenge)) { + bi_mul( verification_commitments[i]->array[j], + verification_commitments[i]->array[j], + verifiable_numbers->array[i]); +#ifdef DAA_DEBUG + DUMP_BI( verification_commitments[i]->array[j]); +#endif + bi_mod( verification_commitments[i]->array[j], + verification_commitments[i]->array[j], + n); + } +#ifdef DAA_DEBUG + if( commitments != NULL && + bi_equals( verification_commitments[i]->array[j], + commitments[i]->array[j]) ==0) { + LogError( "!! ERROR i=%d j=%d\n", i, j); + DUMP_BI( commitments[i]->array[j]); + DUMP_BI( verification_commitments[i]->array[j]); + DUMP_BI( generators->array[i]); + DUMP_BI( proof->response[i]->array[j]); + DUMP_BI( verifiable_numbers->array[i]); + } + printf( "o"); fflush( stdout); +#endif + } + } + // STEP 3 - d + generateMessageDigest( verifiable_challenge, + &length_challenge, + public_key, + verification_commitments, + num_of_variables); + LogDebug("verifiable challenge=%s", + dump_byte_array( length_challenge, verifiable_challenge)); + LogDebug(" challenge=%s", + dump_byte_array( proof->length_challenge, proof->challenge)); + if( length_challenge != proof->length_challenge) { + result = TSS_E_BAD_PARAMETER; + goto close; + } + for( i=0; i<length_challenge; i++) { + if( verifiable_challenge[i] != proof->challenge[i]) { + result = TSS_E_BAD_PARAMETER; + goto close; + } + } + *isCorrect = ( memcmp( verifiable_challenge, proof->challenge, length_challenge) == 0); +close: + if( verification_commitments != NULL) { + for( i = 0; i<num_of_variables; i++) { + bi_free_array( verification_commitments[i]); + } + free( verification_commitments); + } + if( generators != NULL) free( generators); + bi_free( tmp1); + bi_free( tmp); + return result; +} + + +TSS_DAA_PK_PROOF_internal *generate_proof(const bi_ptr product_PQ_prime, + const TSS_DAA_PK_internal *public_key, + const bi_ptr xz, + const bi_ptr x0, + const bi_ptr x1, + bi_array_ptr x +) { + int i, j; + bi_array_ptr generators = get_generators( public_key); + bi_ptr n = public_key->modulus; + int num_of_variables; + int bit_size_message_digest = DAA_PARAM_SIZE_MESSAGE_DIGEST; + bi_array_ptr *xTildes = NULL; + BYTE *challenge_param; + + bi_array_ptr exponents = ALLOC_BI_ARRAY(); + bi_new_array2( exponents, 3 + x->length); + exponents->array[0] = xz; exponents->array[1] = x0; exponents->array[2] = x1; + bi_copy_array( x, 0, exponents, 3, x->length); + num_of_variables = exponents->length; + LogDebug("Step a - choose random numbers"); + LogDebug("\nchoose random numbers\n"); + xTildes = (bi_array_ptr *)malloc( sizeof(bi_array_ptr) * num_of_variables); + if (xTildes == NULL) { + LogError("malloc of %d bytes failed", sizeof(bi_array_ptr) * num_of_variables); + return NULL; + } + for( i=0; i<num_of_variables; i++) { +#ifdef DAA_DEBUG + printf("*"); + fflush(stdout); +#endif + xTildes[i] = ALLOC_BI_ARRAY(); + bi_new_array( xTildes[i], bit_size_message_digest); + compute_random_numbers( xTildes[i], bit_size_message_digest, product_PQ_prime); + } + // Compute commitments + LogDebug("\ncompute commitments"); + bi_array_ptr *commitments = + (bi_array_ptr *)malloc( sizeof(bi_array_ptr) * num_of_variables); + if (commitments == NULL) { + LogError("malloc of %d bytes failed", sizeof(bi_array_ptr) * num_of_variables); + return NULL; + } + for( i=0; i<num_of_variables; i++) { + commitments[i] = ALLOC_BI_ARRAY(); + bi_new_array( commitments[i], bit_size_message_digest); + for( j=0; j<bit_size_message_digest; j++) { +#ifdef DAA_DEBUG + printf("#"); + fflush(stdout); +#endif + bi_mod_exp( commitments[i]->array[j], + generators->array[i], + xTildes[i]->array[j], + n); + } + } +#ifdef DAA_DEBUG + FILE *f=fopen("/tmp/commits", "w"); + for( i=0; i<num_of_variables; i++) { + BI_SAVE_ARRAY( commitments[i], f); + } + fclose(f); +#endif + LogDebug("Step b: compute challenge (message digest)"); + BYTE challenge[EVP_MAX_MD_SIZE]; + int length_challenge; + generateMessageDigest( challenge, + &length_challenge, + public_key, + commitments, + num_of_variables); + // STEP c - compute response + LogDebug("Step c: compute response\n"); + bi_array_ptr *response = (bi_array_ptr *)malloc( sizeof(bi_array_ptr) * num_of_variables); + if (response == NULL) { + LogError("malloc of %d bytes failed", sizeof(bi_array_ptr) * num_of_variables); + return NULL; + } + for( i=0; i<num_of_variables; i++) { + response[i] = ALLOC_BI_ARRAY(); + bi_new_array( response[i], bit_size_message_digest); + for( j=0; j<bit_size_message_digest; j++) { + if( test_bit( j, challenge, length_challenge)) { + bi_sub( response[i]->array[j], + xTildes[i]->array[j], + exponents->array[i]); + } else { + bi_set( response[i]->array[j], + xTildes[i]->array[j]); + } + bi_mod( response[i]->array[j], response[i]->array[j], product_PQ_prime); +#ifdef DAA_DEBUG + printf("#"); + fflush(stdout); +#endif + } + } + challenge_param = (BYTE *)malloc( length_challenge); + if (challenge_param == NULL) { + LogError("malloc of %d bytes failed", length_challenge); + return NULL; + } + memcpy( challenge_param, challenge, length_challenge); + + return create_DAA_PK_PROOF( challenge_param, + length_challenge, + response, + num_of_variables); +} diff --git a/src/tspi/daa/daa_issuer/key_verification.c b/src/tspi/daa/daa_issuer/key_verification.c new file mode 100644 index 0000000..d7584f0 --- /dev/null +++ b/src/tspi/daa/daa_issuer/key_verification.c @@ -0,0 +1,147 @@ +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#include <trousers/tss.h> +#include "spi_internal_types.h" +#include "spi_utils.h" +#include "obj.h" +#include "issuer.h" + +static char *DEFAULT_FILENAME = "issuer.txt"; + +//static TSS_HCONTEXT _hContext; + +static void *intern_alloc( size_t size, TSS_HOBJECT param_alloc) { + // void *ret = calloc_tspi( , size); + void *ret = malloc( size); + LogDebug("[intern_alloc (%d)] -> %d", (int)size, (int)ret); + return ret; +} + +void isCorrect( TSS_HDAA hDAA, + TSS_DAA_PK_internal *pk_internal, + TSS_DAA_PK_PROOF_internal *proof_internal) +{ + TSS_BOOL isCorrect; + TSS_RESULT result; + TSS_DAA_PK *pk; + TSS_DAA_PK_PROOF *pk_proof; + + pk = i_2_e_TSS_DAA_PK( pk_internal, &intern_alloc, (TSS_HOBJECT)NULL); + pk_proof = i_2_e_TSS_DAA_PK_PROOF( proof_internal, + &intern_alloc, + (TSS_HOBJECT)NULL); + result = Tspi_DAA_IssuerKeyVerification( hDAA, + (TSS_HKEY)pk, + pk_proof, + &isCorrect); + if ( result != TSS_SUCCESS ) { + fprintf( stderr, "Tspi_DAA_IssuerKeyVerification error: %d\n", result ); + } + free_TSS_DAA_PK( pk); + printf("isCorrect=%d\n", isCorrect); +} + +int print_usage(char *cmd) { + fprintf(stderr, "usage: %s\n", cmd); + fprintf(stderr, "\t-if,\t--issuer_file\tthe file that will contain\ + all key pair and proof to be used by the issuer (default: %s)\n", DEFAULT_FILENAME); + return -1; +} + +int main(int argc, char *argv[]) { + char *filename = DEFAULT_FILENAME; + int i=1; + char *param; + TSS_RESULT result; + TSS_HCONTEXT hContext; + TSS_HDAA hDAA; + FILE *file; + +// foreground = 1; // for debug + printf("Key Verification (%s:%s,%s)\n", argv[0], __DATE__, __TIME__); + while( i < argc) { + param = argv[ i]; + if( strcmp( param, "-if") == 0 || strcmp( param, "--issuer_file")) { + i++; + if( i == argc) return print_usage( argv[0]); + filename = argv[i]; + } else { + fprintf(stderr, "%s:unrecognized option `%s'\n", argv[0], param); + return print_usage( argv[0]); + } + i++; + } + bi_init( NULL); + printf("Loading issuer info (keypair & proof) -> \'%s\'", filename); + file = fopen( filename, "r"); + if( file == NULL) { + fprintf( stderr, + "%s: Error when opening \'%s\': %s\n", + argv[0], + filename, + strerror( errno)); + return -1; + } + KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof = load_KEY_PAIR_WITH_PROOF( file); + if( key_pair_with_proof == NULL) { + fprintf( stderr, + "%s: Error when reading \'%s\': %s\n", + argv[0], + filename, + strerror( errno)); + return -1; + } + fclose( file); + + // Create Context + printf("\nCreate Context\n"); + result = Tspi_Context_Create( &hContext ); + if ( result != TSS_SUCCESS ) + { + fprintf( stderr, "Tspi_Context_Create %d\n", result ); + exit( result ); + } + + // Connect to Context + printf("\nConnect to the context\n"); + result = Tspi_Context_Connect( hContext, NULL ); + if ( result != TSS_SUCCESS ) + { + fprintf( stderr, "Tspi_Context_Connect error:%d\n", result ); + Tspi_Context_FreeMemory( hContext, NULL ); + Tspi_Context_Close( hContext ); + exit( result ); + } + + //TODO save key in the persistent store + // result = ps_write_key( fd, ) + + //Create Object + result = obj_daa_add( hContext, &hDAA); + if (result != TSS_SUCCESS) { + LogError("Tspi_Context_CreateObject:%d", result); + Tspi_Context_Close(hContext); + LogError("issuer_setup: %s", err_string(result)); + exit(result); + } + + // TSS_HDAA, TSS_HKEY, TSS_DAA_PK_PROOF, TSS_BOOL* + isCorrect( hDAA, key_pair_with_proof->pk, key_pair_with_proof->proof); + obj_daa_remove( hDAA, hContext); + printf("\nClosing the context\n"); + Tspi_Context_FreeMemory( hContext, NULL ); + Tspi_Context_Close( hContext ); + exit( 0 ); +} diff --git a/src/tspi/daa/daa_issuer/keypair_generator.c b/src/tspi/daa/daa_issuer/keypair_generator.c new file mode 100644 index 0000000..9a67254 --- /dev/null +++ b/src/tspi/daa/daa_issuer/keypair_generator.c @@ -0,0 +1,397 @@ +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#include "bi.h" +#include "list.h" +#include "daa_structs.h" +#include "daa_parameter.h" +#include "issuer.h" + +static const int ELEMENT = 0; +static const int EXPONENT = 1; + +extern void prime_init(); +extern void compute_safe_prime(bi_ptr result, int bit_length, int prime_certainty); + +bi_ptr +compute_random_number_star( bi_ptr result, const bi_ptr element) +{ + bi_t bi_tmp; + + bi_new(bi_tmp); + do { + compute_random_number(result, element); + } while (!bi_equals_si(bi_gcd(bi_tmp, result, element), 1)); + + bi_free(bi_tmp); + + return result; +} + +/* Compute a generator of the group of quadratic residue modulo n. The + * generator will not be part of the subgroup of size 2. + * n: modulus */ +void +compute_generator_quadratic_residue(bi_t qr, bi_t n) +{ + bi_t bi_tmp, bi_tmp1; + + bi_new(bi_tmp); + bi_new(bi_tmp1); + + do { + compute_random_number(qr, n); + // qr = (qr ^ bi_2) % n + bi_mod_exp(qr, qr, bi_2, n); + } while (bi_cmp_si(qr, 1) == 0 || + bi_cmp_si(bi_gcd(bi_tmp, n, bi_sub_si(bi_tmp1, qr, 1)), 1) != 0); + + bi_free(bi_tmp); + bi_free(bi_tmp1); +} + +void +compute_group_element(bi_ptr result[], + bi_ptr generator, + bi_ptr product_PQprime, + bi_ptr n) +{ + bi_t bi_tmp; + + bi_new(bi_tmp); + compute_random_number(bi_tmp, product_PQprime); + + // bi_tmp++ + bi_inc(bi_tmp); + + // result[ELEMENT] := (generator ^ bi_tmp) mod n + bi_mod_exp(result[ELEMENT], generator, bi_tmp, n); + bi_set(result[EXPONENT], bi_tmp); + bi_free(bi_tmp); +} + + +TSS_RESULT +generate_key_pair(UINT32 num_attributes_issuer, + UINT32 num_attributes_receiver, + UINT32 base_nameLength, + BYTE* base_name, + KEY_PAIR_WITH_PROOF_internal** key_pair_with_proof) +{ + TSS_RESULT result = TSS_SUCCESS; + int length_mod = DAA_PARAM_SIZE_RSA_MODULUS; + int length; + int i; + TSS_DAA_PK_internal *public_key = NULL; + BYTE *buffer = NULL; + bi_ptr pPrime = NULL; + bi_ptr qPrime = NULL; + bi_ptr n = NULL; + bi_ptr p = NULL; + bi_ptr q = NULL; + bi_ptr capital_s = NULL; + bi_ptr capital_z = NULL; + bi_ptr product_PQprime = NULL; + bi_ptr pair[2] = {NULL, NULL}; + bi_ptr xz = NULL; + bi_ptr capital_r0 = NULL; + bi_ptr x0 = NULL; + bi_ptr capital_r1 = NULL; + bi_ptr x1 = NULL; + bi_array_ptr x = NULL; + bi_array_ptr capital_r = NULL; + bi_array_ptr capitalRReceiver = NULL; + bi_array_ptr capitalRIssuer = NULL; + bi_ptr gamma = NULL; + bi_ptr capital_gamma = NULL; + bi_ptr rho = NULL; + bi_ptr r = NULL; + bi_ptr rho_double = NULL; + bi_t bi_tmp, bi_tmp1, bi_tmp2; + + bi_new(bi_tmp); + bi_new(bi_tmp1); + bi_new(bi_tmp2); + *key_pair_with_proof = NULL; + + // STEP 1 + LogDebug("Step 1 of 8 - compute modulus n (please wait: long process)\n"); + + // FUTURE USAGE if( IS_DEBUG==0) + prime_init(); + p = bi_new_ptr(); + q = bi_new_ptr(); + n = bi_new_ptr(); + + do { + // FUTURE USAGE + /* compute_safe_prime( p, length_mod / 2); + do { + compute_safe_prime( q, + length_mod - (length_mod >> 1)); + } while( bi_cmp( p, q) ==0); + } else */ + { + bi_generate_safe_prime(p, length_mod / 2); + bi_generate_safe_prime(q, length_mod - (length_mod / 2)); + LogDebug("."); + } + // n = p*q + bi_mul(n, p, q); + } while(bi_length(n) != length_mod); + + pPrime = bi_new_ptr(); + bi_sub(pPrime, p, bi_1); + + // pPrime = (p - 1) >> 1 + bi_shift_right(pPrime, pPrime, 1); + qPrime = bi_new_ptr(); + bi_sub(qPrime, q, bi_1); + + // qPrime = (q - 1) >> 1 + bi_shift_right( qPrime, qPrime, 1); + if (bi_is_probable_prime(pPrime) == 0) { + LogError("!! pPrime not a prime number: %s", bi_2_hex_char(pPrime)); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto close; + } + if (bi_is_probable_prime(qPrime) == 0) { + LogError("!! qPrime not a prime number: %s", bi_2_hex_char(qPrime)); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto close; + } + LogDebug("p=%s", bi_2_hex_char(p)); + LogDebug("q=%s", bi_2_hex_char(q)); + LogDebug("n=%s", bi_2_hex_char(n)); + + // STEP 2 + LogDebug("Step 2 - choose random generator of QR_n"); + capital_s = bi_new_ptr(); + compute_generator_quadratic_residue(capital_s, n); + LogDebug("capital_s=%s", bi_2_hex_char(capital_s)); + + // STEP 3 & 4 + LogDebug("Step 3 & 4 - compute group elements"); + product_PQprime = bi_new_ptr(); + bi_mul( product_PQprime, pPrime, qPrime); + pair[ELEMENT] = bi_new_ptr(); + pair[EXPONENT] = bi_new_ptr(); + + LogDebug("product_PQprime=%s [%ld]", bi_2_hex_char(product_PQprime), + bi_nbin_size(product_PQprime)); + + compute_group_element(pair, capital_s, product_PQprime, n); + capital_z = bi_new_ptr(); + bi_set(capital_z, pair[ELEMENT]); + xz = bi_new_ptr(); + bi_set(xz, pair[EXPONENT]); + + // attributes bases + compute_group_element(pair, capital_s, product_PQprime, n); + capital_r0 = bi_new_ptr(); + bi_set(capital_r0, pair[ELEMENT]); + x0 = bi_new_ptr(); + bi_set(x0, pair[EXPONENT]); + + compute_group_element(pair, capital_s, product_PQprime, n); + capital_r1 = bi_new_ptr(); + bi_set(capital_r1, pair[ELEMENT]); + x1 = bi_new_ptr(); + bi_set(x1, pair[EXPONENT]); + + // additional attribute bases + length = num_attributes_issuer + num_attributes_receiver; + x = ALLOC_BI_ARRAY(); + bi_new_array(x, length); + capital_r = ALLOC_BI_ARRAY(); + bi_new_array(capital_r, length); + + for (i = 0; i < length; i++) { + compute_group_element(pair, capital_s, product_PQprime, n); + bi_set(capital_r->array[i], pair[ELEMENT]); + bi_set(x->array[i], pair[EXPONENT]); + } + + // split capitalR into Receiver and Issuer part + capitalRReceiver = ALLOC_BI_ARRAY(); + bi_new_array2(capitalRReceiver, num_attributes_receiver); + for (i = 0; i < num_attributes_receiver; i++) + capitalRReceiver->array[i] = capital_r->array[i]; + capitalRIssuer = ALLOC_BI_ARRAY(); + bi_new_array2(capitalRIssuer, num_attributes_issuer); + for (i = 0; i < num_attributes_issuer; i++) + capitalRIssuer->array[i] = capital_r->array[i + num_attributes_receiver]; + + // STEP 6a + LogDebug("Step 6"); + gamma = bi_new_ptr(); + capital_gamma = bi_new_ptr(); + rho = bi_new_ptr(); + r = bi_new_ptr(); + rho_double = bi_new_ptr(); + + bi_generate_prime(rho, DAA_PARAM_SIZE_RHO); + if (bi_length(rho) != DAA_PARAM_SIZE_RHO) { + LogError("rho bit length=%ld", bi_length(rho)); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto close; + } + + do { + length = DAA_PARAM_SIZE_MODULUS_GAMMA - DAA_PARAM_SIZE_RHO; + do { + bi_urandom(r, length); + } while(bi_length(r) != length || bi_equals_si(bi_mod(bi_tmp, r, rho), 0)); + + // rho is not a dividor of r + bi_mul( capital_gamma, rho, r); + // capital_gamma ++ + bi_inc( capital_gamma); +#ifdef DAA_DEBUG + if (bi_length(capital_gamma) != DAA_PARAM_SIZE_MODULUS_GAMMA) { + printf("|"); fflush(stdout); + } else { + printf("."); fflush(stdout); + } +#endif + } while (bi_length(capital_gamma) != DAA_PARAM_SIZE_MODULUS_GAMMA || + bi_is_probable_prime(capital_gamma) == 0 ); + + // STEP 6b + if (bi_equals(bi_sub_si(bi_tmp, capital_gamma, 1), + bi_mod(bi_tmp1, bi_mul(bi_tmp2, rho, r), n)) == 0) { + LogWarn("capital_gamma-1 != (rho * r) mod n tmp=%s tmp1=%s", + bi_2_hex_char(bi_tmp), bi_2_hex_char(bi_tmp1)); + } + + if (bi_equals(bi_div(bi_tmp, bi_sub_si(bi_tmp1, capital_gamma, 1), rho), r ) == 0) { + LogWarn("( capital_gamma - 1)/rho != r"); + } + + LogDebug("capital_gamma=%s\n", bi_2_hex_char(capital_gamma)); + do { + compute_random_number_star(gamma, capital_gamma); + // gamma = (gamma ^ r) mod capital_gamma + bi_mod_exp(gamma, gamma, r, capital_gamma); + } while (bi_equals(gamma, bi_1)); + // STEP 7 + buffer = (BYTE *)malloc(base_nameLength); + if (buffer == NULL) { + LogError("malloc of %u bytes failed", base_nameLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + memcpy(buffer, base_name, base_nameLength); + // all fields are linked to the struct with direct reference + public_key = create_DAA_PK(n, capital_s, capital_z, capital_r0, capital_r1, gamma, + capital_gamma, rho, capitalRReceiver, capitalRIssuer, + base_nameLength, buffer); + + // STEP 8 + // TODO dynamically load DAAKeyCorrectnessProof + LogDebug("Step 8: generate proof (please wait: long process)"); + TSS_DAA_PK_PROOF_internal *correctness_proof = generate_proof(product_PQprime, public_key, + xz, x0, x1, x); + if (correctness_proof == NULL) { + LogError("creation of correctness_proof failed"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + + *key_pair_with_proof = (KEY_PAIR_WITH_PROOF_internal *) + malloc(sizeof(KEY_PAIR_WITH_PROOF_internal)); + if (*key_pair_with_proof == NULL) { + LogError("malloc of %zd bytes failed", sizeof(KEY_PAIR_WITH_PROOF_internal)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + + (*key_pair_with_proof)->pk = public_key; + (*key_pair_with_proof)->proof = correctness_proof; + // all fields are linked to the struct with direct reference + (*key_pair_with_proof)->private_key = create_TSS_DAA_PRIVATE_KEY(pPrime, qPrime); +close: + if (result != TSS_SUCCESS) { + // remove everything, even numbers that should be stored in a struct + FREE_BI(pPrime); // kept if no error + FREE_BI(qPrime); // kept if no error + FREE_BI(n); // kept if no error + // FREE_BI( p); + // FREE_BI( q); + FREE_BI(capital_s); // kept if no error + FREE_BI(capital_z); // kept if no error + // FREE_BI(product_PQprime); + // FREE_BI(pair[ELEMENT]); + // FREE_BI(pair[EXPONENT]); + // FREE_BI(xz); + FREE_BI(capital_r0); // kept if no error + // FREE_BI(x0); + FREE_BI(capital_r1); // kept if no error + // FREE_BI( x1); + // bi_array_ptr x = NULL; + // bi_array_ptr capital_r = NULL; + // bi_array_ptr capitalRReceiver = NULL; + // bi_array_ptr capitalRIssuer = NULL; + FREE_BI( gamma); // kept if no error + FREE_BI( capital_gamma); // kept if no error + FREE_BI( rho); // kept if no error + // FREE_BI( r); + // FREE_BI( rho_double); + if (buffer!=NULL) + free(buffer); + + if (public_key != NULL) + free(public_key); + + if (*key_pair_with_proof != NULL) + free(*key_pair_with_proof); + } + /* + Fields kept by structures + TSS_DAA_PK: n + capital_s + capital_z + capital_r0 + capital_r1 + gamma + capital_gamma + rho + capitalRReceiver + capitalRIssuer + base_nameLength + buffer + TSS_DAA_PRIVATE_KEY: + pPrime + qPrime + */ + bi_free(bi_tmp); + bi_free(bi_tmp1); + bi_free(bi_tmp2); + FREE_BI(p); + FREE_BI(q); + FREE_BI(product_PQprime); + FREE_BI(pair[ELEMENT]); + FREE_BI(pair[EXPONENT]); + FREE_BI(xz); + FREE_BI(x0); + FREE_BI(x0); + // bi_array_ptr x = NULL; + // bi_array_ptr capital_r = NULL; + // bi_array_ptr capitalRReceiver = NULL; + // bi_array_ptr capitalRIssuer = NULL; + FREE_BI(r); + FREE_BI(rho_double); + + return result; +} diff --git a/src/tspi/daa/daa_issuer/prime_gen.c b/src/tspi/daa/daa_issuer/prime_gen.c new file mode 100644 index 0000000..27c4026 --- /dev/null +++ b/src/tspi/daa/daa_issuer/prime_gen.c @@ -0,0 +1,327 @@ +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004, 2005 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "bi.h" +#include "list.h" +#include "tsplog.h" + +static unsigned long *primes; +static int primes_length; + +/* Generates a random number of bit_length bit length. The first two bits and the last bit of this + * number are always set, therefore the number is odd and >= (2^(bit_length-1)+2^(bit_length-2)+1) + * + * bit_length: The length of the number to be generated, in bits + * return: a random number of bitLength bit length with first and last bits set + */ +void +random_odd_bi(bi_ptr bi, int bit_length) +{ + if (bit_length > 0) { + bi_urandom(bi, bit_length); + //bi_generate_prime(bi, bit_length); + bi_setbit(bi, 0); + bi_setbit(bi, bit_length - 1); + bi_setbit(bi, bit_length - 2); + } +} + +/* This method generates small prime numbers up to a specified bounds using the Sieve of + * Eratosthenes algorithm. + * + * prime_bound: the upper bound for the primes to be generated + * starting_prime: the first prime in the list of primes that is returned + * return: list of primes up to the specified bound. Each prime is of type bi_ptr + */ +void +generate_small_primes(int prime_bound, int starting_prime) +{ + list_ptr res; + int length; + int *is_primes; + int i; + int k; + int prime; + node_t *current; + + primes_length = 0; + res = list_new(); + if (allocs == NULL) { + LogError("malloc of list failed"); + return; + } + if ((prime_bound <= 1) || (starting_prime > prime_bound)) + return; + + if (starting_prime <= 2) { + starting_prime = 2; + list_add(res, bi_2); + } + length = (prime_bound - 1) >> 1; // length = (prime_bound -1) / 2; + is_primes = (int *)malloc(sizeof(int)*length); + if (is_primes == NULL) { + LogError("malloc of %zd bytes failed", sizeof(int) * length); + return; + } + + for (i = 0; i < length; i++) + is_primes[i] = 1; + + for (i = 0; i < length; i++) { + if (is_primes[i] == 1) { + prime = 2 * i + 3; + for (k = i + prime; k < length; k+= prime) + is_primes[k] = 0; + + if (prime >= starting_prime) { + list_add(res, (void *)prime); + primes_length++; + } + } + } + // converti the list to a table + current = res->head; // go to first node + primes = (unsigned long *)malloc(sizeof(unsigned long) * primes_length); + if (primes == NULL) { + LogError("malloc of %d bytes failed", + sizeof(unsigned long)*primes_length); + return; + } + + i = 0; + while (current != NULL) { + primes[i++] = (unsigned long)current->obj; + current = current->next; // traverse through the list + } + + free(is_primes); + list_freeall(res); +} + +void +prime_init() +{ + generate_small_primes(16384, 3); +} + +/* Test whether the provided pDash or p = 2*pDash + 1 are divisible by any of the small primes + * saved in the listOfSmallPrimes. A limit for the largest prime to be tested against can be + * specified, but it will be ignored if it exeeds the number of precalculated primes. + * + * p_dash: the number to be tested (p_dash) + * prime_bound: the limit for the small primes to be tested against. + */ +static int +test_small_prime_factors(const bi_ptr p_dash, const unsigned long prime_bound) +{ + int sievePassed = 1; + unsigned long r; + unsigned long small_prime; + bi_t temp; bi_new(temp); + + small_prime = 1; + int i = 0; + while (i < primes_length && small_prime < prime_bound ) { + small_prime = primes[i++]; + // r = p_dash % small_prime + bi_mod_si(temp, p_dash, small_prime); + r = bi_get_si(temp); + // test if pDash = 0 (mod smallPrime) + if (r == 0) { + sievePassed = 0; + break; + } + // test if p = 0 (mod smallPrime) (or r == smallPrime - r - 1) + if (r == (small_prime - r - 1)) { + sievePassed = 0; + break; + } + } + bi_free(temp); + + return sievePassed; +} + +/* Tests if a is a Miller-Rabin witness for n + * + * a: number which is supposed to be the witness + * n: number to be tested against + * return: true if a is Miller-Rabin witness for n, false otherwise + */ +int +is_miller_rabin_witness(const bi_ptr a, const bi_ptr n) +{ + bi_t n_1; + bi_t temp; + bi_t _2_power_t; + bi_t u; + bi_t x0; + bi_t x1; + int t = -1; + int i; + + bi_new(n_1); + bi_new(temp); + bi_new(_2_power_t); + bi_new(u); + + // n1 = n - 1 + bi_sub_si(n_1, n, 1); + + // test if n-1 = 2^t*u with t >= 1 && u even + do { + t++; + // _2_power_t = bi_1 << t ( == 2 ^ t) + bi_shift_left(_2_power_t, bi_1, t); + // u = n_1 / (2 ^ t) + bi_div(u, n_1, _2_power_t); + } while (bi_equals_si(bi_mod(temp, u, bi_2), 0)); + + bi_new(x0); + bi_new(x1); + + // x1 = (a ^ u ) % n + bi_mod_exp(x1, a, u, n); + + // finished to use u, _2_power_t and temp + bi_free(u); + bi_free(_2_power_t); + bi_free(temp); + for (i = 0; i < t; i++) { + bi_set(x0, x1); + + // x1 = (x0 ^ 2) % n + bi_mod_exp(x1, x0, bi_2, n); + if (bi_equals_si(x1, 1) && !bi_equals_si(x0, 1) && !bi_equals(x0, n_1) != 0) { + bi_free(x0); + bi_free(x1); + bi_free(n_1); + return 1; + } + } + + bi_free(x0); + bi_free(x1); + bi_free(n_1); + + if (!bi_equals(x1, bi_1)) + return 1; + + return 0; +} + +bi_ptr +compute_trivial_safe_prime(bi_ptr result, int bit_length) +{ + LogDebugFn("Enter"); + do { + bi_generate_prime(result, bit_length-1); + bi_shift_left(result, result, 1); // result := result << 1 + bi_add_si(result, result, 1); // result := result -1 + if (getenv("TSS_DEBUG_OFF") == NULL) { + printf("."); + fflush(stdout); + } + } while (bi_is_probable_prime(result)==0); + + return result; +} + +/* The main method to compute a random safe prime of the specified bit length. + * IMPORTANT: The computer prime will have two first bits and the last bit set to 1 !! + * i.e. > (2^(bitLength-1)+2^(bitLength-2)+1). This is done to be sure that if two primes of + * bitLength n are multiplied, the result will have the bitLenght of 2*n exactly This + * implementation uses the algorithm proposed by Ronald Cramer and Victor Shoup in "Signature + * Schemes Based on the strong RSA Assumption" May 9, 2000. + * + * bitLength: the bit length of the safe prime to be computed. + * return: a number which is considered to be safe prime + */ +bi_ptr +compute_safe_prime(bi_ptr p, int bit_length) +{ + bi_ptr p_dash; + bi_ptr temp_p; + bi_ptr p_minus_1; + int stop; + unsigned long prime_bound; + + LogDebug("compute Safe Prime: length: %d bits\n", bit_length); + + p_dash = bi_new_ptr(); + temp_p = bi_new_ptr(); + p_minus_1 = bi_new_ptr(); + + /* some heuristic checks to limit the number of small primes to check against and the + * number of Miller-Rabin primality tests at the end */ + if (bit_length <= 256) { + prime_bound = 768; + } else if (bit_length <= 512) { + prime_bound = 3072; + } else if (bit_length <= 768) { + prime_bound = 6144; + } else if (bit_length <= 1024) { + prime_bound = 1024; + } else { + prime_bound = 16384; + } + + do { + stop = 0; + /* p_dash = generated random with basic bit settings (odd) */ + random_odd_bi(p_dash, bit_length - 1); + + if (test_small_prime_factors(p_dash, prime_bound) == 0) { + LogDebugFn("1"); + continue; + } + /* test if p_dash or p are divisible by some small primes */ + if (is_miller_rabin_witness(bi_2, p_dash)) { + LogDebugFn("2"); + continue; + } + /* test if 2^(pDash) = +1/-1 (mod p) + * bi can not handle negative operation, we compare to (p-1) instead of -1 + * calculate p = 2*pDash+1 -> (pDash << 1) + 1 + */ + bi_shift_left(p, p_dash, 1); + bi_add(p, p, bi_1); + + // p_minus_1:= p - 1 + bi_sub(p_minus_1, p, bi_1); + + // temp_p := ( 2 ^ p_dash ) mod p + bi_mod_exp(temp_p, bi_2, p_dash, p); + if (!bi_equals_si(temp_p, 1) && !bi_equals(temp_p, p_minus_1) ) { + LogDebugFn("3"); + continue; + } + + // test if pDash or p are divisible by some small primes + if (is_miller_rabin_witness(bi_2, p_dash)) { + LogDebugFn("4"); + continue; + } + // test the library dependent probable_prime + if (bi_is_probable_prime(p_dash)) + stop = 1; + } while (stop == 0); + + bi_free(p_minus_1); + bi_free(temp_p); + bi_free(p_dash); + + LogDebug("found Safe Prime: %s bits", bi_2_hex_char(p)); + + return p; +} diff --git a/src/tspi/daa/daa_parameter.c b/src/tspi/daa/daa_parameter.c new file mode 100644 index 0000000..58f240f --- /dev/null +++ b/src/tspi/daa/daa_parameter.c @@ -0,0 +1,184 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + +#include "daa_parameter.h" + +setenv("TCSD_FOREGROUND", "1", 1); + +static EVP_MD *digest = NULL; + +extern EVP_MD *DAA_PARAM_get_message_digest(void) { + if( digest == NULL) { + OpenSSL_add_all_digests(); + digest = EVP_get_digestbyname( DAA_PARAM_MESSAGE_DIGEST_ALGORITHM); + } + return digest; +} + +// from common.c (ltp-tss) +char *err_string(TSS_RESULT r) +{ + /* Check the return code to see if it is common to all layers. + * If so, return it. + */ + switch (TSS_ERROR_CODE(r)) { + case TSS_SUCCESS: return "TSS_SUCCESS"; + default: + break; + } + + /* The return code is either unknown, or specific to a layer */ + if (TSS_ERROR_LAYER(r) == TSS_LAYER_TPM) { + switch (TSS_ERROR_CODE(r)) { + case TCPA_E_AUTHFAIL: return "TCPA_E_AUTHFAIL"; + case TCPA_E_BADINDEX: return "TCPA_E_BADINDEX"; + case TCPA_E_AUDITFAILURE: return "TCPA_E_AUDITFAILURE"; + case TCPA_E_CLEAR_DISABLED: return "TCPA_E_CLEAR_DISABLED"; + case TCPA_E_DEACTIVATED: return "TCPA_E_DEACTIVATED"; + case TCPA_E_DISABLED: return "TCPA_E_DISABLED"; + case TCPA_E_DISABLED_CMD: return "TCPA_E_DISABLED_CMD"; + case TCPA_E_FAIL: return "TCPA_E_FAIL"; + case TCPA_E_INACTIVE: return "TCPA_E_INACTIVE"; + case TCPA_E_INSTALL_DISABLED: return "TCPA_E_INSTALL_DISABLED"; + case TCPA_E_INVALID_KEYHANDLE: return "TCPA_E_INVALID_KEYHANDLE"; + case TCPA_E_KEYNOTFOUND: return "TCPA_E_KEYNOTFOUND"; + case TCPA_E_NEED_SELFTEST: return "TCPA_E_NEED_SELFTEST"; + case TCPA_E_MIGRATEFAIL: return "TCPA_E_MIGRATEFAIL"; + case TCPA_E_NO_PCR_INFO: return "TCPA_E_NO_PCR_INFO"; + case TCPA_E_NOSPACE: return "TCPA_E_NOSPACE"; + case TCPA_E_NOSRK: return "TCPA_E_NOSRK"; + case TCPA_E_NOTSEALED_BLOB: return "TCPA_E_NOTSEALED_BLOB"; + case TCPA_E_OWNER_SET: return "TCPA_E_OWNER_SET"; + case TCPA_E_RESOURCES: return "TCPA_E_RESOURCES"; + case TCPA_E_SHORTRANDOM: return "TCPA_E_SHORTRANDOM"; + case TCPA_E_SIZE: return "TCPA_E_SIZE"; + case TCPA_E_WRONGPCRVAL: return "TCPA_E_WRONGPCRVAL"; + case TCPA_E_BAD_PARAM_SIZE: return "TCPA_E_BAD_PARAM_SIZE"; + case TCPA_E_SHA_THREAD: return "TCPA_E_SHA_THREAD"; + case TCPA_E_SHA_ERROR: return "TCPA_E_SHA_ERROR"; + case TCPA_E_FAILEDSELFTEST: return "TCPA_E_FAILEDSELFTEST"; + case TCPA_E_AUTH2FAIL: return "TCPA_E_AUTH2FAIL"; + case TCPA_E_BADTAG: return "TCPA_E_BADTAG"; + case TCPA_E_IOERROR: return "TCPA_E_IOERROR"; + case TCPA_E_ENCRYPT_ERROR: return "TCPA_E_ENCRYPT_ERROR"; + case TCPA_E_DECRYPT_ERROR: return "TCPA_E_DECRYPT_ERROR"; + case TCPA_E_INVALID_AUTHHANDLE: return "TCPA_E_INVALID_AUTHHANDLE"; + case TCPA_E_NO_ENDORSEMENT: return "TCPA_E_NO_ENDORSEMENT"; + case TCPA_E_INVALID_KEYUSAGE: return "TCPA_E_INVALID_KEYUSAGE"; + case TCPA_E_WRONG_ENTITYTYPE: return "TCPA_E_WRONG_ENTITYTYPE"; + case TCPA_E_INVALID_POSTINIT: return "TCPA_E_INVALID_POSTINIT"; + case TCPA_E_INAPPROPRIATE_SIG: return "TCPA_E_INAPPROPRIATE_SIG"; + case TCPA_E_BAD_KEY_PROPERTY: return "TCPA_E_BAD_KEY_PROPERTY"; + case TCPA_E_BAD_MIGRATION: return "TCPA_E_BAD_MIGRATION"; + case TCPA_E_BAD_SCHEME: return "TCPA_E_BAD_SCHEME"; + case TCPA_E_BAD_DATASIZE: return "TCPA_E_BAD_DATASIZE"; + case TCPA_E_BAD_MODE: return "TCPA_E_BAD_MODE"; + case TCPA_E_BAD_PRESENCE: return "TCPA_E_BAD_PRESENCE"; + case TCPA_E_BAD_VERSION: return "TCPA_E_BAD_VERSION"; + case TCPA_E_RETRY: return "TCPA_E_RETRY"; + default: return "UNKNOWN TPM ERROR"; + } + } else if (TSS_ERROR_LAYER(r) == TSS_LAYER_TDDL) { + switch (TSS_ERROR_CODE(r)) { + case TSS_E_FAIL: return "TSS_E_FAIL"; + case TSS_E_BAD_PARAMETER: return "TSS_E_BAD_PARAMETER"; + case TSS_E_INTERNAL_ERROR: return "TSS_E_INTERNAL_ERROR"; + case TSS_E_NOTIMPL: return "TSS_E_NOTIMPL"; + case TSS_E_PS_KEY_NOTFOUND: return "TSS_E_PS_KEY_NOTFOUND"; + case TSS_E_KEY_ALREADY_REGISTERED: return "TSS_E_KEY_ALREADY_REGISTERED"; + case TSS_E_CANCELED: return "TSS_E_CANCELED"; + case TSS_E_TIMEOUT: return "TSS_E_TIMEOUT"; + case TSS_E_OUTOFMEMORY: return "TSS_E_OUTOFMEMORY"; + case TSS_E_TPM_UNEXPECTED: return "TSS_E_TPM_UNEXPECTED"; + case TSS_E_COMM_FAILURE: return "TSS_E_COMM_FAILURE"; + case TSS_E_TPM_UNSUPPORTED_FEATURE: return "TSS_E_TPM_UNSUPPORTED_FEATURE"; + case TDDL_E_COMPONENT_NOT_FOUND: return "TDDL_E_COMPONENT_NOT_FOUND"; + case TDDL_E_ALREADY_OPENED: return "TDDL_E_ALREADY_OPENED"; + case TDDL_E_BADTAG: return "TDDL_E_BADTAG"; + case TDDL_E_INSUFFICIENT_BUFFER: return "TDDL_E_INSUFFICIENT_BUFFER"; + case TDDL_E_COMMAND_COMPLETED: return "TDDL_E_COMMAND_COMPLETED"; + case TDDL_E_ALREADY_CLOSED: return "TDDL_E_ALREADY_CLOSED"; + case TDDL_E_IOERROR: return "TDDL_E_IOERROR"; + default: return "UNKNOWN TDDL ERROR"; + } + } else if (TSS_ERROR_LAYER(r) == TSS_LAYER_TCS) { + switch (TSS_ERROR_CODE(r)) { + case TSS_E_FAIL: return "TSS_E_FAIL"; + case TSS_E_BAD_PARAMETER: return "TSS_E_BAD_PARAMETER"; + case TSS_E_INTERNAL_ERROR: return "TSS_E_INTERNAL_ERROR"; + case TSS_E_NOTIMPL: return "TSS_E_NOTIMPL"; + case TSS_E_PS_KEY_NOTFOUND: return "TSS_E_PS_KEY_NOTFOUND"; + case TSS_E_KEY_ALREADY_REGISTERED: return "TSS_E_KEY_ALREADY_REGISTERED"; + case TSS_E_CANCELED: return "TSS_E_CANCELED"; + case TSS_E_TIMEOUT: return "TSS_E_TIMEOUT"; + case TSS_E_OUTOFMEMORY: return "TSS_E_OUTOFMEMORY"; + case TSS_E_TPM_UNEXPECTED: return "TSS_E_TPM_UNEXPECTED"; + case TSS_E_COMM_FAILURE: return "TSS_E_COMM_FAILURE"; + case TSS_E_TPM_UNSUPPORTED_FEATURE: return "TSS_E_TPM_UNSUPPORTED_FEATURE"; + case TCS_E_KEY_MISMATCH: return "TCS_E_KEY_MISMATCH"; + case TCS_E_KM_LOADFAILED: return "TCS_E_KM_LOADFAILED"; + case TCS_E_KEY_CONTEXT_RELOAD: return "TCS_E_KEY_CONTEXT_RELOAD"; + case TCS_E_INVALID_CONTEXTHANDLE: return "TCS_E_INVALID_CONTEXTHANDLE"; + case TCS_E_INVALID_KEYHANDLE: return "TCS_E_INVALID_KEYHANDLE"; + case TCS_E_INVALID_AUTHHANDLE: return "TCS_E_INVALID_AUTHHANDLE"; + case TCS_E_INVALID_AUTHSESSION: return "TCS_E_INVALID_AUTHSESSION"; + case TCS_E_INVALID_KEY: return "TCS_E_INVALID_KEY"; + default: return "UNKNOWN TCS ERROR"; + } + } else { + switch (TSS_ERROR_CODE(r)) { + case TSS_E_FAIL: return "TSS_E_FAIL"; + case TSS_E_BAD_PARAMETER: return "TSS_E_BAD_PARAMETER"; + case TSS_E_INTERNAL_ERROR: return "TSS_E_INTERNAL_ERROR"; + case TSS_E_NOTIMPL: return "TSS_E_NOTIMPL"; + case TSS_E_PS_KEY_NOTFOUND: return "TSS_E_PS_KEY_NOTFOUND"; + case TSS_E_KEY_ALREADY_REGISTERED: return "TSS_E_KEY_ALREADY_REGISTERED"; + case TSS_E_CANCELED: return "TSS_E_CANCELED"; + case TSS_E_TIMEOUT: return "TSS_E_TIMEOUT"; + case TSS_E_OUTOFMEMORY: return "TSS_E_OUTOFMEMORY"; + case TSS_E_TPM_UNEXPECTED: return "TSS_E_TPM_UNEXPECTED"; + case TSS_E_COMM_FAILURE: return "TSS_E_COMM_FAILURE"; + case TSS_E_TPM_UNSUPPORTED_FEATURE: return "TSS_E_TPM_UNSUPPORTED_FEATURE"; + case TSS_E_INVALID_OBJECT_TYPE: return "TSS_E_INVALID_OBJECT_TYPE"; + case TSS_E_INVALID_OBJECT_INITFLAG: return "TSS_E_INVALID_OBJECT_INITFLAG"; + case TSS_E_INVALID_HANDLE: return "TSS_E_INVALID_HANDLE"; + case TSS_E_NO_CONNECTION: return "TSS_E_NO_CONNECTION"; + case TSS_E_CONNECTION_FAILED: return "TSS_E_CONNECTION_FAILED"; + case TSS_E_CONNECTION_BROKEN: return "TSS_E_CONNECTION_BROKEN"; + case TSS_E_HASH_INVALID_ALG: return "TSS_E_HASH_INVALID_ALG"; + case TSS_E_HASH_INVALID_LENGTH: return "TSS_E_HASH_INVALID_LENGTH"; + case TSS_E_HASH_NO_DATA: return "TSS_E_HASH_NO_DATA"; + case TSS_E_SILENT_CONTEXT: return "TSS_E_SILENT_CONTEXT"; + case TSS_E_INVALID_ATTRIB_FLAG: return "TSS_E_INVALID_ATTRIB_FLAG"; + case TSS_E_INVALID_ATTRIB_SUBFLAG: return "TSS_E_INVALID_ATTRIB_SUBFLAG"; + case TSS_E_INVALID_ATTRIB_DATA: return "TSS_E_INVALID_ATTRIB_DATA"; + case TSS_E_NO_PCRS_SET: return "TSS_E_NO_PCRS_SET"; + case TSS_E_KEY_NOT_LOADED: return "TSS_E_KEY_NOT_LOADED"; + case TSS_E_KEY_NOT_SET: return "TSS_E_KEY_NOT_SET"; + case TSS_E_VALIDATION_FAILED: return "TSS_E_VALIDATION_FAILED"; + case TSS_E_TSP_AUTHREQUIRED: return "TSS_E_TSP_AUTHREQUIRED"; + case TSS_E_TSP_AUTH2REQUIRED: return "TSS_E_TSP_AUTH2REQUIRED"; + case TSS_E_TSP_AUTHFAIL: return "TSS_E_TSP_AUTHFAIL"; + case TSS_E_TSP_AUTH2FAIL: return "TSS_E_TSP_AUTH2FAIL"; + case TSS_E_KEY_NO_MIGRATION_POLICY: return "TSS_E_KEY_NO_MIGRATION_POLICY"; + case TSS_E_POLICY_NO_SECRET: return "TSS_E_POLICY_NO_SECRET"; + case TSS_E_INVALID_OBJ_ACCESS: return "TSS_E_INVALID_OBJ_ACCESS"; + case TSS_E_INVALID_ENCSCHEME: return "TSS_E_INVALID_ENCSCHEME"; + case TSS_E_INVALID_SIGSCHEME: return "TSS_E_INVALID_SIGSCHEME"; + case TSS_E_ENC_INVALID_LENGTH: return "TSS_E_ENC_INVALID_LENGTH"; + case TSS_E_ENC_NO_DATA: return "TSS_E_ENC_NO_DATA"; + case TSS_E_ENC_INVALID_TYPE: return "TSS_E_ENC_INVALID_TYPE"; + case TSS_E_INVALID_KEYUSAGE: return "TSS_E_INVALID_KEYUSAGE"; + case TSS_E_VERIFICATION_FAILED: return "TSS_E_VERIFICATION_FAILED"; + case TSS_E_HASH_NO_IDENTIFIER: return "TSS_E_HASH_NO_IDENTIFIER"; + default: return "UNKNOWN TSS ERROR"; + } + } +} diff --git a/src/tspi/daa/daa_platform/platform.c b/src/tspi/daa/daa_platform/platform.c new file mode 100644 index 0000000..80180ca --- /dev/null +++ b/src/tspi/daa/daa_platform/platform.c @@ -0,0 +1,2644 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +// for message digest +#include <openssl/evp.h> +#include <openssl/hmac.h> +#include <openssl/err.h> +#include <openssl/rsa.h> +#include <openssl/sha.h> + +#include <stdlib.h> + +#include "daa_structs.h" +#include "daa_parameter.h" +#include "trousers/tss.h" +#include "spi_internal_types.h" +#include "spi_utils.h" +#include <trousers/trousers.h> +#include <spi_utils.h> +#include <obj.h> +#include "tsplog.h" +#include "tss/tcs.h" +#include "platform.h" +#include "issuer.h" +#include "verifier.h" + +#define EVP_SUCCESS 1 + +TSS_RESULT +Tcsip_TPM_DAA_Join(TCS_CONTEXT_HANDLE tcsContext, // in + TSS_HDAA hDAA, // in + BYTE stage, // in + UINT32 inputSize0, // in + BYTE* inputData0, // in + UINT32 inputSize1, // in + BYTE* inputData1, // in + TPM_AUTH* ownerAuth, // in/out + UINT32* outputSize, // out + BYTE** outputData // out +) { + TSS_RESULT result; + TSS_HPOLICY hPolicy; + TCPA_DIGEST digest; + UINT16 offset = 0; + BYTE hashblob[10000]; + TPM_HANDLE hTPM; + TPM_HANDLE join_session; + // TPM_HANDLE hTPM; + + if( (result = obj_daa_get_handle_tpm( hDAA, &hTPM)) != TSS_SUCCESS) + return result; + if( (result = obj_daa_get_session_handle( hDAA, &join_session)) != TSS_SUCCESS) + return result; + LogDebug("Tcsip_TPM_DAA_Join(tcsContext=%x,hDAA=%x,join_session=%x, hTPM=%x stage=%d)", + tcsContext, + hDAA, + join_session, + hTPM, + stage); + + LogDebug("obj_tpm_get_policy(hTPM=%X)", hTPM); + if( (result = obj_tpm_get_policy( hTPM, &hPolicy)) != TSS_SUCCESS) + return result; + LogDebug("Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Join, hashblob)"); + // hash TPM_COMMAND_CODE + Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Join, hashblob); + LogDebug("Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest)"); + // hash stage + Trspi_LoadBlob_BYTE(&offset, stage, hashblob); + LogDebug("Trspi_LoadBlob_UINT32(&offset, 0, hashblob)"); + // hash inputSize0 + Trspi_LoadBlob_UINT32(&offset, inputSize0, hashblob); + LogDebug("Trspi_LoadBlob_UINT32(&offset, inputSize0:%d", inputSize0); + // hash inputData0 + Trspi_LoadBlob( &offset, inputSize0, hashblob, inputData0); + // hash inputSize1 + Trspi_LoadBlob_UINT32(&offset, inputSize1, hashblob); + LogDebug("Trspi_LoadBlob_UINT32(&offset, inputSize1:%d", inputSize1); + // hash inputData1 + Trspi_LoadBlob( &offset, inputSize1, hashblob, inputData1); + Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest); + + if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_DAA_Join, + hPolicy, &digest, + ownerAuth)) != TSS_SUCCESS) return result; + LogDebug("secret_PerformAuth_OIAP(hTPM, TPM_ORD_DAA_Join ret=%d", result); + LogDebug("TCSP_DAAJoin(%x,%x,stage=%x,%x,%x,%x,%x,%x)\n", + tcsContext, + hTPM, + stage, + inputSize0, + (int)inputData0, + inputSize1, + (int)inputData1, + (int)&ownerAuth); + /* step of the following call: + TCSP_DAAJoin tcsd_api/calltcsapi.c (define in spi_utils.h) + TCSP_DAAJoin_TP tcsd_api/tcstp.c (define in trctp.h) + */ + result = TCSP_DaaJoin( tcsContext, + join_session, + stage, + inputSize0, inputData0, + inputSize1, inputData1, + ownerAuth, + outputSize, outputData); + if( result != TSS_SUCCESS) return result; + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, result, hashblob); + Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Join, hashblob); + Trspi_LoadBlob_UINT32(&offset, *outputSize, hashblob); + Trspi_LoadBlob(&offset, *outputSize, hashblob, *outputData); + LogDebug("TCSP_DAAJoin stage=%d outputSize=%d outputData=%x RESULT=%d", + (int)stage, (int)*outputSize, (int)outputData, (int)result); + Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest); + if( (result = obj_policy_validate_auth_oiap( hPolicy, &digest, ownerAuth))) { + LogError("obj_policy_validate_auth=%d", result); + } + return result; +} + +TSS_RESULT Tcsip_TPM_DAA_Sign( TCS_CONTEXT_HANDLE hContext, // in + TPM_HANDLE handle, // in + BYTE stage, // in + UINT32 inputSize0, // in + BYTE* inputData0, // in + UINT32 inputSize1, // in + BYTE* inputData1, // in + TPM_AUTH* ownerAuth, // in, out + UINT32* outputSize, // out + BYTE** outputData // out +) { + TSS_RESULT result; + TSS_HPOLICY hPolicy; + TCPA_DIGEST digest; + UINT16 offset = 0; + BYTE hashblob[1000]; + TPM_HANDLE hTPM; + TPM_HANDLE session_handle; + TSS_HDAA hDAA = (TSS_HDAA)handle; + // TPM_HANDLE hTPM; + + if( (result = obj_daa_get_handle_tpm( hDAA, &hTPM)) != TSS_SUCCESS) + return result; + if( (result = obj_daa_get_session_handle( hDAA, &session_handle)) != TSS_SUCCESS) + return result; + LogDebug("Tcsip_TPM_DAA_Sign(tcsContext=%x,hDAA=%x,sign_session=%x, hTPM=%x stage=%d)", + hContext, + hDAA, + session_handle, + hTPM, + stage); + + LogDebug("obj_tpm_get_policy(hTPM=%X)", hTPM); + if( (result = obj_tpm_get_policy( hTPM, &hPolicy)) != TSS_SUCCESS) + return result; + LogDebug("Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Sign, hashblob)"); + // hash TPM_COMMAND_CODE + Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Sign, hashblob); + LogDebug("Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest)"); + // hash stage + Trspi_LoadBlob_BYTE(&offset, stage, hashblob); + LogDebug("Trspi_LoadBlob_UINT32(&offset, 0, hashblob)"); + // hash inputSize0 + Trspi_LoadBlob_UINT32(&offset, inputSize0, hashblob); + LogDebug("Trspi_LoadBlob_UINT32(&offset, inputSize0:%d", inputSize0); + // hash inputData0 + Trspi_LoadBlob( &offset, inputSize0, hashblob, inputData0); + // hash inputSize1 + Trspi_LoadBlob_UINT32(&offset, inputSize1, hashblob); + LogDebug("Trspi_LoadBlob_UINT32(&offset, inputSize1:%d", inputSize1); + // hash inputData1 + Trspi_LoadBlob( &offset, inputSize1, hashblob, inputData1); + Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest); + + if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_DAA_Join, + hPolicy, &digest, + ownerAuth)) != TSS_SUCCESS) return result; + LogDebug("secret_PerformAuth_OIAP(hTPM, TPM_ORD_DAA_Join ret=%d", result); + LogDebug("TCSP_DAASign(%x,%x,stage=%x,%x,%x,%x,%x,%x)", + hContext, + hTPM, + stage, + inputSize0,(int)inputData0, + inputSize1,(int)inputData1, + (int)&ownerAuth); + /* step of the following call: + TCSP_DAASign tcsd_api/calltcsapi.c (define in spi_utils.h) + TCSP_DAASign_TP tcsd_api/tcstp.c (define in trctp.h) + */ + result = TCSP_DaaSign( hContext, + session_handle, + stage, + inputSize0, inputData0, + inputSize1, inputData1, + ownerAuth, + outputSize, outputData); + if( result != TSS_SUCCESS) return result; + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, result, hashblob); + Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Sign, hashblob); + Trspi_LoadBlob_UINT32(&offset, *outputSize, hashblob); + Trspi_LoadBlob(&offset, *outputSize, hashblob, *outputData); + LogDebug("TCSP_DAASign stage=%d outputSize=%d outputData=%x RESULT=%d", + (int)stage, (int)*outputSize, (int)outputData, (int)result); + Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest); + if( (result = obj_policy_validate_auth_oiap( hPolicy, &digest, ownerAuth))) + { + LogError("obj_policy_validate_auth=%d", result); + } + return result; +} + +/** + Only used for the logging +*/ +static TSS_RESULT +Tcsip_TPM_DAA_Join_encapsulate(TCS_CONTEXT_HANDLE tcsContext, // in + TSS_HDAA hDAA, // in + BYTE stage, // in + UINT32 inputSize0, // in + BYTE* inputData0, // in + UINT32 inputSize1, // in + BYTE* inputData1, // in + TPM_AUTH* ownerAuth, // in/out + UINT32* outputSize, // out + BYTE** outputData // out +) { + TSS_RESULT result; + + LogDebug("Tcsip_DAA_Join(TCS_CONTEXT=%X,TSS_HDAA=%X,stage=%d,\ + inputSize0=%u,inputData0=%s\ninputSize1=%u,inputData1=%s,ownerAuth=%X)", + tcsContext, hDAA, stage, + inputSize0, dump_byte_array(inputSize0, inputData0), + inputSize1,dump_byte_array(inputSize1, inputData1), + (int)ownerAuth); + result = Tcsip_TPM_DAA_Join( + tcsContext, // in + hDAA, // in + stage, // in + inputSize0, // in + inputData0, // in + inputSize1, // in + inputData1, // in + ownerAuth, // in/out + outputSize, // out + outputData // out + ); + LogDebug("Tcsip_DAA_Join(stage=%d,outputSize=%u outputData=%s ownerAuth=%X) result=%d", + (int)stage, *outputSize, dump_byte_array( *outputSize, *outputData), (int)ownerAuth, result); + return result; +} + +#if 0 +/* from TSS.java */ +/* openssl RSA (struct rsa_st) could manage RSA Key */ +TSS_RESULT +Tspi_TPM_DAA_JoinInit_internal( TSS_HDAA hDAA, + TSS_HTPM hTPM, + int daa_counter, + TSS_DAA_PK *issuer_pk, + int issuer_authentication_PKLengh, + RSA **issuer_authentication_PK, + int issuer_authentication_PK_signaturesLength, + BYTE **issuer_authentication_PK_signatures, + int *capital_UprimeLength, + BYTE **capital_Uprime, + TSS_DAA_IDENTITY_PROOF *identity_proof, + TSS_DAA_JOIN_SESSION *join_session) +{ + // Optional: verification of the PKDAA and issuer settings (authen. by the RSA Public Key chain) + TSS_RESULT result; + TCS_CONTEXT_HANDLE tcsContext; + TPM_AUTH ownerAuth; + int i, modulus_length, outputSize, length, length1; + UINT32 return_join_session; + BYTE *outputData, *issuer_settings_bytes; + BYTE *buffer_modulus; + TPM_DAA_ISSUER *issuer_settings; + char buffer[1000], buffer1[1000]; + TSS_DAA_PK_internal *pk_internal = e_2_i_TSS_DAA_PK( issuer_pk); + bi_ptr issuer_authentication_PK_i = NULL; + + if( (result = obj_tpm_is_connected( hTPM, &tcsContext)) != TSS_SUCCESS) + return result; + obj_daa_set_handle_tpm( hDAA, hTPM); + + // stages 0-2 explained in the diagram "Keys of DAA Issuer" + // issuer_authentication_PKLengh should be converted to Network Based integer + i = htonl(issuer_authentication_PKLengh); + result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA, + 0, + sizeof(int), (BYTE *)(&i), + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) { goto close;} + // set the sessionHandle to the returned value + return_join_session = ntohl( *((UINT32 *)outputData)); + free( outputData); + obj_daa_set_session_handle( hDAA, return_join_session); + + LogDebug("done join 0 settings join_session:%x\n", return_join_session); + modulus_length = DAA_PARAM_SIZE_RSA_MODULUS / 8; + buffer_modulus = malloc(modulus_length); + if (buffer_modulus == NULL) { + LogError("malloc of %d bytes failed", modulus_length); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + issuer_authentication_PK_i = bi_new_ptr(); + for(i =0; i< issuer_authentication_PKLengh; i++) { + bi_set_as_BIGNUM( issuer_authentication_PK_i, issuer_authentication_PK[i]->n); + bi_2_byte_array( buffer_modulus, + modulus_length, + issuer_authentication_PK_i); + if ( i==0) { + result = Tcsip_TPM_DAA_Join_encapsulate( + tcsContext, hDAA, + 1, + modulus_length, buffer_modulus, + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) { + free( buffer_modulus); + goto close; + } + } else { + result = Tcsip_TPM_DAA_Join_encapsulate( + tcsContext, hDAA, + 1, + modulus_length, buffer_modulus, + DAA_PARAM_KEY_SIZE / 8, issuer_authentication_PK_signatures[i -1], + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) { + free( buffer_modulus); + goto close; + } + } + } + free( buffer_modulus); + LogDebug("done join 1-%d\n", issuer_authentication_PKLengh); + // define issuer_settings + issuer_settings = convert2issuer_settings( pk_internal); + issuer_settings_bytes = issuer_2_byte_array( issuer_settings, &length); + result = Tcsip_TPM_DAA_Join_encapsulate( + tcsContext, hDAA, + 2, + length, issuer_settings_bytes, + modulus_length, + issuer_authentication_PK_signatures[issuer_authentication_PKLengh-1], + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) { goto close;} + LogDebug("done join 2\n"); + i = htonl( daa_counter); + result = Tcsip_TPM_DAA_Join_encapsulate( + tcsContext, hDAA, + 3, + sizeof(UINT32), (BYTE *)(&i), + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) { goto close;} + LogDebug("done join 3\n"); + // reserved another buffer for storing Big Integer + bi_2_nbin1( &length, buffer, pk_internal->capitalR0); + bi_2_nbin1( &length1, buffer1, pk_internal->modulus); + result = Tcsip_TPM_DAA_Join_encapsulate( + tcsContext, hDAA, + 4, + length, buffer, + length1, buffer1, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) { goto close;} + LogDebug("done join 4\n"); + bi_2_nbin1( &length, buffer, pk_internal->capitalR1); + result = Tcsip_TPM_DAA_Join_encapsulate( + tcsContext, hDAA, + 5, + length, buffer, + length1, buffer1, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) { goto close;} + LogDebug("done join 5\n"); + bi_2_nbin1( &length, buffer, pk_internal->capitalS); + result = Tcsip_TPM_DAA_Join_encapsulate( + tcsContext, hDAA, + 6, + length, buffer, + length1, buffer1, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) { goto close;} + LogDebug("done join 6\n"); + bi_2_nbin1( &length, buffer, pk_internal->capitalSprime); + // define Uprime + result = Tcsip_TPM_DAA_Join_encapsulate( + tcsContext, hDAA, + 7, + length, buffer, + length1, buffer1, + &ownerAuth, &outputSize, &outputData); + // 5 : save PKDAA, U, daaCount and sessionHandle in joinSession + join_session->issuerPk = (TSS_HKEY)issuer_pk; + if( result == TSS_SUCCESS) { + *capital_UprimeLength = outputSize; + *capital_Uprime = convert_alloc( tcsContext, outputSize, outputData); + if (*capital_Uprime == NULL) { + LogError("malloc of %d bytes failed", outputSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + join_session->capitalUPrime = copy_alloc( tcsContext, + *capital_UprimeLength, + *capital_Uprime); + if (join_session->capitalUPrime == NULL) { + LogError("malloc of %d bytes failed", *capital_UprimeLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + join_session->capitalUPrimeLength = *capital_UprimeLength; + } + join_session->sessionHandle = return_join_session; + // get the endorsement Key (public part) + result = get_public_EK( + hTPM, // in + &( identity_proof->endorsementLength), + &( identity_proof->endorsementCredential) + ); + +close: + FREE_BI( issuer_authentication_PK_i); + LogDebug("result = %d", result); + LogDebug("outputSize=%d", outputSize); + LogDebug("outputData=%s", dump_byte_array( outputSize, outputData)); + return result; +} +#else +TSS_RESULT +Tspi_TPM_DAA_JoinInit_internal(TSS_HTPM hTPM, + TSS_HDAA_ISSUER_KEY hIssuerKey + UINT32 daa_counter, + UINT32 issuerAuthPKsLength, + TSS_HKEY* issuerAuthPKs, + UINT32 issuerAuthPKSignaturesLength, + UINT32 issuerAuthPKSignaturesLength2, + BYTE** issuerAuthPKSignatures, + UINT32* capitalUprimeLength, + BYTE** capitalUprime, + TSS_DAA_IDENTITY_PROOF** identity_proof, + UINT32* joinSessionLength, + BYTE** joinSession) +{ + // Optional: verification of the PKDAA and issuer settings (authen. by the RSA Public Key chain) + TSS_RESULT result; + TSS_HCONTEXT tspContext; + TPM_AUTH ownerAuth; + int length, length1; + UINT32 i, modulus_length, outputSize, buf_len; + BYTE *outputData, *issuer_settings_bytes; + BYTE *modulus, stage, *buf; + //TPM_DAA_ISSUER *issuer_settings; + //char buffer[1000], buffer1[1000]; + //TSS_DAA_PK_internal *pk_internal = e_2_i_TSS_DAA_PK(issuer_pk); + bi_ptr issuerAuthPK = NULL; + TPM_HANDLE daaHandle; + Trspi_HashCtx hashCtx; + TPM_DIGEST digest; + TSS_DAA_IDENTITY_PROOF daaIdentityProof; + + if ((result = obj_tpm_is_connected(hTPM, &tspContext))) + return result; + + if ((result = obj_daaissuerkey_get_daa_handle(hIssuerKey, &daaHandle))) + return result; + + stage = 0; + inputSize0 = (UINT32)sizeof(UINT32); + inputData0 = issuerAuthPKsLength; + inputSize1 = 0; + inputData1 = NULL; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_DAA_Join); + result |= Trspi_Hash_BYTE(&hashCtx, stage); + result |= Trspi_Hash_UINT32(&hashCtx, inputSize0); + result |= Trspi_HashUpdate(&hashCtx, inputSize0, inputData0); + result |= Trspi_Hash_UINT32(&hashCtx, inputSize1); + result |= Trspi_HashUpdate(&hashCtx, inputSize1, inputData1); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + // stages 0-2 explained in the diagram "Keys of DAA Issuer" + if ((result = TCS_API(tspContext)->DaaJoin(tspContext, daaHandle, stage, inputSize1, + inputData0, inputSize1, inputData1, &ownerAuth, + &outputSize, &outputData))) + goto close; + + if (outputSize != sizeof(UINT32)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto close; + } + + // set the sessionHandle to the returned value + Trspi_UnloadBlob_UINT32(&offset, &daaHandle, outputData); + free(outputData); + if ((result = obj_daaissuerkey_set_daa_handle(hIssuerKey, daaHandle))) + goto close; + + LogDebug("done join 0 settings join_session:%x", daaHandle); + + modulus_length = DAA_PARAM_SIZE_RSA_MODULUS / 8; + if ((buffer_modulus = malloc(modulus_length)) == NULL) { + LogError("malloc of %d bytes failed", modulus_length); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + + stage = 1; + for (i = 0; i < issuerAuthPKsLength; i++) { + if ((result = obj_rsakey_get_modulus(issuerAuthPKs[i], &modulus_length, &modulus))) + goto close; + + outputData = NULL; + if (i==0) { + result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage, + modulus_length, modulus, 0, NULL, + &ownerAuth, &outputSize, + &outputData); + } else { + result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage, + modulus_length, modulus, + issuerAuthPKSignaturesLength2, + issuerAuthPKSignatures[i - 1], + &ownerAuth, &outputSize, + &outputData); + } + + free(outputData); + free_tspi(tspContext, modulus); + if (result != TSS_SUCCESS) { + LogDebugFn("Stage 1 iteration %u failed", i); + goto close; + } + } + + LogDebug("done join 1-%d\n", issuer_authentication_PKLengh); + + stage = 2; + // define issuer_settings +#if 0 + issuer_settings = convert2issuer_settings(pk_internal); + issuer_settings_bytes = issuer_2_byte_array(issuer_settings, &length); +#else + if ((result = obj_daaissuerkey_get_daa_issuer(hIssuerKey, &issuer_length, &issuer))) + goto close; + + if ((result = obj_daaissuerkey_get_modulus(hIssuerKey, &modulus_length, &modulus))) { + free_tspi(tspContext, issuer); + goto close; + } +#endif + if ((result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage, issuer_length, + issuer, issuerAuthPKSignaturesLength2, + issuerAuthPKSignatures[i - 1], &ownerAuth, + &outputSize, &outputData))) { + free_tspi(tspContext, issuer); + free_tspi(tspContext, modulus); + goto close; + } + free_tspi(tspContext, issuer); + + LogDebug("done join 2\n"); + + stage = 3; + if ((result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage, sizeof(UINT32), + (BYTE *)(&daa_counter), 0, NULL, &ownerAuth, + &outputSize, &outputData))) + goto close; + + LogDebug("done join 3\n"); + + stage = 4; +#if 0 + // reserved another buffer for storing Big Integer + bi_2_nbin1( &length, buffer, pk_internal->capitalR0); + bi_2_nbin1( &length1, buffer1, pk_internal->modulus); +#else + if ((result = obj_daaissuerkey_get_capitalR0(hIssuerKey, &buf_len, &buf))) + return result; +#endif + if ((result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage, buf_len, buf, + modulus_length, modulus, &ownerAuth, + &outputSize, &outputData))) { + free_tspi(tspContext, buf); + free_tspi(tspContext, modulus); + goto close; + } + free_tspi(tspContext, buf); + + LogDebug("done join 4\n"); + + stage = 5; +#if 0 + bi_2_nbin1( &length, buffer, pk_internal->capitalR1); +#else + if ((result = obj_daaissuerkey_get_capitalR1(hIssuerKey, &buf_len, &buf))) + return result; +#endif + if ((result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage, buf_len, + buf, modulus_length, modulus, &ownerAuth, + &outputSize, &outputData))) { + free_tspi(tspContext, buf); + free_tspi(tspContext, modulus); + goto close; + } + free_tspi(tspContext, buf); + + LogDebug("done join 5\n"); + + stage = 6; +#if 0 + bi_2_nbin1( &length, buffer, pk_internal->capitalS); +#else + if ((result = obj_daaissuerkey_get_capitalS(hIssuerKey, &buf_len, &buf))) + return result; +#endif + if ((result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage, buf_len, buf, + modulus_length, modulus, &ownerAuth, + &outputSize, &outputData))) { + free_tspi(tspContext, buf); + free_tspi(tspContext, modulus); + goto close; + } + free_tspi(tspContext, buf); + + LogDebug("done join 6\n"); + + stage = 7; +#if 0 + bi_2_nbin1( &length, buffer, pk_internal->capitalSprime); +#else + if ((result = obj_daaissuerkey_get_capitalSprime(hIssuerKey, &buf_len, &buf))) + return result; +#endif + // define Uprime + if ((result = Tcsip_TPM_DAA_Join_encapsulate(tspContext, daaHandle, stage, buf_len, buf, + modulus_length, modulus, &ownerAuth, + &outputSize, &outputData))) { + free_tspi(tspContext, buf); + free_tspi(tspContext, modulus); + goto close; + } + free_tspi(tspContext, buf); + +#if 0 + // 5 : save PKDAA, U, daaCount and sessionHandle in joinSession + join_session->issuerPk = (TSS_HKEY)issuer_pk; + if( result == TSS_SUCCESS) { + *capital_UprimeLength = outputSize; + *capital_Uprime = convert_alloc( tspContext, outputSize, outputData); + if (*capital_Uprime == NULL) { + LogError("malloc of %d bytes failed", outputSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + join_session->capitalUPrime = copy_alloc( tspContext, + *capital_UprimeLength, + *capital_Uprime); + if (join_session->capitalUPrime == NULL) { + LogError("malloc of %d bytes failed", *capital_UprimeLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + join_session->capitalUPrimeLength = *capital_UprimeLength; + } + join_session->sessionHandle = return_join_session; + // get the endorsement Key (public part) + result = get_public_EK( + hTPM, // in + &( identity_proof->endorsementLength), + &( identity_proof->endorsementCredential) + ); +#else + /* fill out the identity proof struct */ + if ((result = TCS_API(obj->tspContext)->GetTPMCapability(obj->tspContext, TPM_CAP_VERSION, + 0, NULL, &buf_len, &buf))) + goto close; + + offset = 0; + Trspi_UnloadBlob_VERSION(&offset, buf, &daaIdentityProof.versionInfo); + free_tspi(tspContext, buf); + +#error set all 3 credentials in the daaIdentityProof struct here + + /* set the U data */ + if ((result = __tspi_add_mem_entry(tspContext, outputData))) + goto close; + *capitalUPrime = outputData; + *capitalUPrimeLength = outputSize; + + /* return the TSS specific stuff */ +#endif + +close: + FREE_BI( issuer_authentication_PK_i); + LogDebug("result = %d", result); + LogDebug("outputSize=%d", outputSize); + LogDebug("outputData=%s", dump_byte_array( outputSize, outputData)); + return result; +} +#endif + + +/* allocation: + endorsementKey as BYTE * +*/ +TSS_RESULT +get_public_EK(TSS_HTPM hTPM, + UINT32 *endorsementKeyLength, + BYTE **endorsementKey + +) { + TSS_RESULT result; + TSS_HKEY hEk; + TSS_HPOLICY hTpmPolicy; + UINT32 uiAttrSize; + BYTE *pAttr; + + if( (result = obj_tpm_get_policy( hTPM, &hTpmPolicy)) != TSS_SUCCESS) { + LogError("can not retrieve policy from the TPM handler"); + goto out_close; + } + + if( (result = Tspi_TPM_GetPubEndorsementKey(hTPM, TRUE, NULL, &hEk)) != TSS_SUCCESS) { + LogError("can not retrieve the Public endorsed Key"); + goto out_close; + } + + result = Tspi_GetAttribData( + hEk, + TSS_TSPATTRIB_KEY_INFO, + TSS_TSPATTRIB_KEYINFO_VERSION, + &uiAttrSize, + &pAttr); + + if (result != TSS_SUCCESS) goto out_close; + LogDebug("keyinfo:%s", dump_byte_array( uiAttrSize, pAttr)); + + result = Tspi_GetAttribData( + hEk, + TSS_TSPATTRIB_KEY_BLOB, + TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY, + endorsementKeyLength, + endorsementKey); + + LogDebug("Public Endorsement Key:%s", + dump_byte_array( *endorsementKeyLength, *endorsementKey)); +out_close: + return result; +} + +// from TSS.java (479) +TSS_RESULT +compute_join_challenge_host(TSS_HDAA hDAA, + TSS_DAA_PK_internal *pk_internal, + bi_ptr capitalU, + bi_ptr capital_Uprime, + bi_ptr capital_utilde, + bi_ptr capital_utilde_prime, + bi_ptr capital_ni, + bi_ptr capital_ni_tilde, + UINT32 commitments_proofLength, + TSS_DAA_ATTRIB_COMMIT_internal * + commitments_proof, + UINT32 nonceIssuerLength, + BYTE* nonceIssuer, + UINT32 *resultLength, + BYTE **result) { + EVP_MD_CTX mdctx; + BYTE *encoded_pk = NULL, *buffer; + UINT32 encoded_pkLength; + int rv, length; + + buffer = (BYTE *)malloc( 10000); // to be sure, and it will be free quickly + if (buffer == NULL) { + LogError("malloc of %d bytes failed", 10000); + return TSPERR(TSS_E_OUTOFMEMORY); + } + // EVP_MD_CTX_init(&mdctx); + rv = EVP_DigestInit(&mdctx, DAA_PARAM_get_message_digest()); + if (rv != EVP_SUCCESS) goto err; + // allocation + encoded_pk = encoded_DAA_PK_internal( &encoded_pkLength, pk_internal); + LogDebug("encoded issuerPk[%d]: %s", + encoded_pkLength, + dump_byte_array( encoded_pkLength, encoded_pk)); + rv = EVP_DigestUpdate(&mdctx, encoded_pk, encoded_pkLength); + if (rv != EVP_SUCCESS) goto err; + // capitalU + length = DAA_PARAM_SIZE_RSA_MODULUS / 8; + bi_2_byte_array( buffer, length, capitalU); + LogDebug("capitalU[%ld]: %s", + bi_nbin_size(capitalU) , + dump_byte_array( length, buffer)); + rv = EVP_DigestUpdate(&mdctx, buffer, length); + if (rv != EVP_SUCCESS) goto err; + // capital UPrime + bi_2_byte_array( buffer, length, capital_Uprime); + LogDebug("capitalUPrime[%d]: %s", + length, + dump_byte_array( length, buffer)); + rv = EVP_DigestUpdate(&mdctx, buffer, length); + if (rv != EVP_SUCCESS) goto err; + // capital Utilde + bi_2_byte_array( buffer, length, capital_utilde); + LogDebug("capitalUTilde[%d]: %s", + length, + dump_byte_array( length, buffer)); + rv = EVP_DigestUpdate(&mdctx, buffer, length); + if (rv != EVP_SUCCESS) goto err; + // capital UtildePrime + bi_2_byte_array( buffer, length, capital_utilde_prime); + LogDebug("capital_utilde_prime[%d]: %s", + length, + dump_byte_array( length, buffer)); + rv = EVP_DigestUpdate(&mdctx, buffer, length); + if (rv != EVP_SUCCESS) goto err; + //capital_ni + length = DAA_PARAM_SIZE_MODULUS_GAMMA / 8; + bi_2_byte_array( buffer, length, capital_ni); + LogDebug("capital_ni[%d]: %s", + length, + dump_byte_array( length, buffer)); + rv = EVP_DigestUpdate(&mdctx, buffer, length); + if (rv != EVP_SUCCESS) goto err; + //capital_ni_tilde + bi_2_byte_array( buffer, length, capital_ni_tilde); + LogDebug("capital_ni_tilde[%d]: %s", + length, + dump_byte_array( length, buffer)); + rv = EVP_DigestUpdate(&mdctx, buffer, length); + if (rv != EVP_SUCCESS) goto err; + // TODO: commitments + LogDebug("nonceIssuer[%d]: %s", + nonceIssuerLength, + dump_byte_array( nonceIssuerLength, nonceIssuer)); + rv = EVP_DigestUpdate(&mdctx, nonceIssuer, nonceIssuerLength); + if (rv != EVP_SUCCESS) goto err; + *resultLength = EVP_MD_CTX_size(&mdctx); + *result = (BYTE *)malloc( *resultLength); + if (*result == NULL) { + LogError("malloc of %d bytes failed", *resultLength); + free( buffer); + free( encoded_pk); + return TSPERR(TSS_E_OUTOFMEMORY); + } + rv = EVP_DigestFinal(&mdctx, *result, NULL); + if (rv != EVP_SUCCESS) goto err; + free( buffer); + free( encoded_pk); + return TSS_SUCCESS; +err: + free( buffer); + free( encoded_pk); + DEBUG_print_openssl_errors(); + return TSPERR(TSS_E_INTERNAL_ERROR); +} + +/* +This is the second out of 3 functions to execute in order to receive a DAA Credential. It +computes the credential request for the DAA Issuer, which also includes the Platforms & DAA +public key and the attributes that were chosen by the Platform, and which are not visible to \ +the DAA Issuer. The Platform can commit to the attribute values it has chosen. +Code influenced by TSS.java (TssDaaCredentialRequest) +*/ +TSPICALL +Tspi_TPM_DAA_JoinCreateDaaPubKey_internal( + TSS_HDAA hDAA, // in + TSS_HTPM hTPM, // in + UINT32 authenticationChallengeLength, // in + BYTE* authenticationChallenge, // in + UINT32 nonceIssuerLength, // in + BYTE* nonceIssuer, // in + UINT32 attributesPlatformLength, // in + BYTE** attributesPlatform, // in + TSS_DAA_JOIN_SESSION* joinSession, // in, out + TSS_DAA_CREDENTIAL_REQUEST* credentialRequest // out +) { + TSS_RESULT result; + TCS_CONTEXT_HANDLE tcsContext; + TPM_AUTH ownerAuth; + bi_ptr tmp1 = bi_new_ptr(); + bi_ptr tmp2 = bi_new_ptr(); + bi_ptr capital_utilde = bi_new_ptr(); + bi_ptr v_tilde_prime = bi_new_ptr(); + bi_ptr rv_tilde_prime = bi_new_ptr(); + bi_ptr capitalU = bi_new_ptr(); + bi_ptr product_attributes = bi_new_ptr(); + bi_ptr capital_ni = NULL; + bi_ptr capital_utilde_prime = NULL; + bi_ptr capital_ni_tilde = NULL; + bi_ptr n = NULL; + bi_ptr attributePlatform = NULL; + bi_ptr c = NULL; + bi_ptr zeta = NULL; + bi_ptr capital_Uprime = NULL; + bi_ptr sv_tilde_prime = NULL; + bi_ptr s_f0 = NULL; + bi_ptr s_f1 = NULL; + bi_ptr sv_prime = NULL; + bi_ptr sv_prime1 = NULL; + bi_ptr sv_prime2 = NULL; + bi_array_ptr ra = NULL; + bi_array_ptr sa = NULL; + TSS_DAA_PK* pk_extern = (TSS_DAA_PK *)joinSession->issuerPk; + TSS_DAA_PK_internal* pk_internal = e_2_i_TSS_DAA_PK( pk_extern); + UINT32 i, outputSize, authentication_proofLength, nonce_tpmLength; + UINT32 capitalSprime_byte_arrayLength, size_bits, length, chLength, c_byteLength; + UINT32 internal_cbyteLength, noncePlatformLength; + BYTE *outputData, *authentication_proof, *capitalSprime_byte_array = NULL, *buffer; + BYTE *ch = NULL; + BYTE *c_byte, *noncePlatform, *nonce_tpm; + BYTE *internal_cbyte = NULL; + EVP_MD_CTX mdctx; + + if( tmp1 == NULL || tmp2 == NULL || capital_utilde == NULL || + v_tilde_prime == NULL || rv_tilde_prime == NULL || + capitalU == NULL || product_attributes == NULL) { + LogError("malloc of bi(s) failed"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + if( pk_internal == NULL) { + LogError("malloc of pk_internal failed"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + if( (result = obj_tpm_is_connected( hTPM, &tcsContext)) != TSS_SUCCESS) { + goto close; + } + obj_daa_set_handle_tpm( hDAA, hTPM); + // allocation + n = bi_set_as_nbin( pk_extern->modulusLength, pk_extern->modulus); + if( n == NULL) { + LogError("malloc of %d bytes failed", pk_extern->modulusLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + // allocation + capitalSprime_byte_array = bi_2_nbin( &capitalSprime_byte_arrayLength, + pk_internal->capitalSprime); + if( capitalSprime_byte_array == NULL) { + LogError("malloc of %d bytes failed", capitalSprime_byte_arrayLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + // compute second part of the credential request + // encode plateform attributes (the one visible only by the receiver) + bi_set( product_attributes, bi_1); + for( i=0; i<attributesPlatformLength; i++) { + attributePlatform = bi_set_as_nbin( DAA_PARAM_SIZE_F_I / 8, + attributesPlatform[i]); // allocation + if( attributePlatform == NULL) { + LogError("malloc of bi <%s> failed", "attributePlatform"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + // bi_tmp1 = ( capitalRReceiver[i] ^ attributesPlatform ) % n + bi_mod_exp( tmp1, pk_internal->capitalRReceiver->array[i], attributePlatform, n); + // bi_tmp1 = bi_tmp1 * product_attributes + bi_mul( tmp1, tmp1, product_attributes); + // product_attributes = bi_tmp1 % n + bi_mod( product_attributes, tmp1, n); + bi_free_ptr( attributePlatform); + } + bi_urandom( v_tilde_prime, DAA_PARAM_SIZE_RSA_MODULUS + + DAA_PARAM_SAFETY_MARGIN); + // tmp1 = capitalUPrime * capitalS + bi_free_ptr( tmp1); + tmp1 = bi_set_as_nbin( joinSession->capitalUPrimeLength, + joinSession->capitalUPrime); // allocation + if( tmp1 == NULL) { + LogError("malloc of %d bytes failed", joinSession->capitalUPrimeLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + // U = ( U' * ( ( pk->S ^ v~' ) % n) ) % n + // tmp2 = ( pk->S ^ v~') % n + bi_mod_exp( tmp2, pk_internal->capitalS, v_tilde_prime, n); + // U = tmp1( U') * tmp2 + bi_mul( capitalU, tmp1, tmp2); + bi_mod( capitalU, capitalU, n); + // U = ( U * product_attributes ) % n + bi_mul( capitalU, capitalU, product_attributes); + bi_mod( capitalU, capitalU, n); + // 2 : call the TPM to compute authentication proof with U' + result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA, + 8, + authenticationChallengeLength, authenticationChallenge, + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + LogDebug("Done Join 8"); + authentication_proof = calloc_tspi( tcsContext, outputSize); + if( authentication_proof == NULL) { + LogError("malloc of %d bytes failed", outputSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + memcpy( authentication_proof, outputData, outputSize); + free( outputData); + authentication_proofLength = outputSize; + + // 3 : call the TPM to compute U' (first part of correctness proof of the credential + // request + result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA, + 9, + pk_extern->capitalR0Length, pk_extern->capitalR0, + pk_extern->modulusLength, pk_extern->modulus, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + LogDebug("Done Join 9: capitalR0"); + free( outputData); + + result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA, + 10, + pk_extern->capitalR1Length, pk_extern->capitalR1, + pk_extern->modulusLength, pk_extern->modulus, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + LogDebug("Done Join 10: capitalR1"); + free( outputData); + + result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA, + 11, + pk_extern->capitalSLength, pk_extern->capitalS, + pk_extern->modulusLength, pk_extern->modulus, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + LogDebug("Done Join 11: capitalS"); + free( outputData); + + result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA, + 12, + capitalSprime_byte_arrayLength, capitalSprime_byte_array, + pk_extern->modulusLength, pk_extern->modulus, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + LogDebug("Done Join 12: capitalUTildePrime"); + capital_utilde_prime = bi_set_as_nbin( outputSize, outputData); // allocation + if( capital_utilde_prime == NULL) { + LogError("malloc of %d bytes failed", outputSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + free( outputData); + // 4 compute pseudonym with respect to the DAA Issuer + // allocation + zeta = compute_zeta( pk_internal->issuerBaseNameLength, + pk_internal->issuerBaseName, + pk_internal); + if( zeta == NULL) { + LogError("malloc of bi <%s> failed", "zeta"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + buffer = (BYTE *)malloc( TPM_DAA_SIZE_w); + if( buffer == NULL) { + LogError("malloc of %d bytes failed", TPM_DAA_SIZE_w); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + LogDebug("zeta[%ld] = %s", bi_nbin_size( zeta), bi_2_hex_char( zeta)); + bi_2_byte_array( buffer, TPM_DAA_SIZE_w, zeta); + LogDebug("zeta[%d] = %s", TPM_DAA_SIZE_w, dump_byte_array( TPM_DAA_SIZE_w, buffer)); + + result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA, + 13, + pk_extern->capitalGammaLength, pk_extern->capitalGamma, + TPM_DAA_SIZE_w, buffer, // zeta + &ownerAuth, &outputSize, &outputData); + free( buffer); + if( result != TSS_SUCCESS) goto close; + LogDebug("Done Join 13: capitalGamma / zeta"); + free( outputData); + + result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA, + 14, + pk_extern->capitalGammaLength, pk_extern->capitalGamma, + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + LogDebug("Done Join 14: capitalGamma"); + capital_ni = bi_set_as_nbin( outputSize, outputData); // allocation + if( capital_ni == NULL) { + LogError("malloc of bi <%s> failed", "capital_ni"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + free( outputData); + + result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA, + 15, + pk_extern->capitalGammaLength, pk_extern->capitalGamma, + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + LogDebug("Done Join 15: capitalGamma"); + capital_ni_tilde = bi_set_as_nbin( outputSize, outputData); // allocation + if( capital_ni_tilde == NULL) { + LogError("malloc of bi <%s> failed", "capital_ni_tilde"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + free( outputData); + + // 5 : compute the second part of the correctness proof of the credential request + // (with attributes not visible to issuer) + // randomize/blind attributesReceiver + size_bits = DAA_PARAM_SIZE_RANDOMIZED_ATTRIBUTES; + bi_set( product_attributes, bi_1); + ra = (bi_array_ptr)malloc( sizeof( struct _bi_array)); + if( ra == NULL) { + LogError("malloc of %d bytes failed", sizeof( struct _bi_array)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_new_array( ra, attributesPlatformLength); + if( ra->array == NULL) { + LogError("malloc of bi_array <%s> failed", "ra"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + for( i=0; i < attributesPlatformLength; i++) { + bi_urandom( ra->array[i], size_bits); + LogDebug("ra[i]=%s size=%d", bi_2_hex_char( ra->array[i]), size_bits); + // product_attributes=(((capitalYplatform ^ ra[i]) % n)*<product_attributes-1>)%n + bi_mod_exp( tmp1, pk_internal->capitalRReceiver->array[i], ra->array[i], n); + bi_mul( tmp1, tmp1, product_attributes); + bi_mod( product_attributes, tmp1, n); + } + size_bits = DAA_PARAM_SIZE_F_I+2*DAA_PARAM_SAFETY_MARGIN+DAA_PARAM_SIZE_MESSAGE_DIGEST; + bi_urandom( rv_tilde_prime, size_bits); + // capital_utilde = ( capitalS ^ rv_tilde_prime) % n + bi_mod_exp( capital_utilde, pk_internal->capitalS, rv_tilde_prime, n); + // capital_utilde = capital_utilde * product_attributes + bi_mul( capital_utilde, capital_utilde, product_attributes); + // capital_utilde = capital_utilde % n + bi_mod( capital_utilde, capital_utilde, n); + // 5e + capital_Uprime = bi_set_as_nbin( joinSession->capitalUPrimeLength, + joinSession->capitalUPrime); // allocation + if( capital_Uprime == NULL) { + LogError("malloc of bi <%s> failed", "capital_Uprime"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + LogDebug("calculation UTilde: capitalS:%s\n", bi_2_hex_char( pk_internal->capitalS)); + LogDebug("calculation UTilde: rv_tilde_prime:%s\n", bi_2_hex_char( rv_tilde_prime)); + LogDebug("calculation UTilde: n:%s\n", bi_2_hex_char( n)); + LogDebug("calculation UTilde: product_attributes:%s\n", bi_2_hex_char( product_attributes)); + LogDebug("calculation NItilde: ntilde:%s\n", bi_2_hex_char( capital_ni_tilde)); + + result = compute_join_challenge_host( + hDAA, + pk_internal, + capitalU, + capital_Uprime, + capital_utilde, + capital_utilde_prime, + capital_ni, + capital_ni_tilde, + 0, // TODO commitmentProofLength + NULL, // TODO commitment + nonceIssuerLength, + nonceIssuer, + &chLength, // out + &ch // out allocation + ); + if( result != TSS_SUCCESS) goto close; + + result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA, + 16, + chLength, ch, + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + nonce_tpm = outputData; + nonce_tpmLength = outputSize; + LogDebug("Done Join 16: compute_join_challenge_host return nonce_tpm:%s", + dump_byte_array(nonce_tpmLength, nonce_tpm)); + + result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA, + 17, + 0, NULL, + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + s_f0 = bi_set_as_nbin( outputSize, outputData); // allocation + if( s_f0 == NULL) { + LogError("malloc of <bi> %s failed", "s_f0"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + LogDebug("Done Join 17: return sF0:%s", dump_byte_array(outputSize, outputData) ); + free( outputData); + + result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA, + 18, + 0, NULL, + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + s_f1 = bi_set_as_nbin( outputSize, outputData); // allocation + if( s_f1 == NULL) { + LogError("malloc of <bi> %s failed", "s_f1"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + LogDebug("Done Join 18: return sF1:%s", dump_byte_array(outputSize, outputData) ); + free( outputData); + + result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA, + 19, + 0, NULL, + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + LogDebug("Done Join 19: return sv_prime1"); + sv_prime1 = bi_set_as_nbin( outputSize, outputData); // allocation + if( sv_prime1 == NULL) { + LogError("malloc of <bi> %s failed", "sv_prime1"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + free( outputData); + + result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA, + 20, + 0, NULL, + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + LogDebug("Done Join 20: return cByte"); + c_byte = (BYTE *)calloc_tspi( tcsContext, outputSize); + if( c_byte == NULL) { + LogError("malloc of %d bytes failed", outputSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + memcpy( c_byte, outputData, outputSize); + free( outputData); + c_byteLength = outputSize; + c = bi_set_as_nbin( c_byteLength, c_byte); // allocation + if( c == NULL) { + LogError("malloc of <bi> %s failed", "c"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + + // verify computation of c by TPM + EVP_DigestInit(&mdctx, DAA_PARAM_get_message_digest()); + EVP_DigestUpdate(&mdctx, ch, chLength); + EVP_DigestUpdate(&mdctx, nonce_tpm, nonce_tpmLength); + nonce_tpm = convert_alloc( tcsContext, nonce_tpmLength, nonce_tpm); // allocation + if( nonce_tpm == NULL) { + LogError("malloc of %d bytes failed", nonce_tpmLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + internal_cbyteLength = EVP_MD_CTX_size(&mdctx); + internal_cbyte = (BYTE *)malloc( internal_cbyteLength); + if( internal_cbyte == NULL) { + LogError("malloc of %d bytes failed", internal_cbyteLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + EVP_DigestFinal(&mdctx, internal_cbyte, NULL); + if( c_byteLength != internal_cbyteLength || + memcmp( c_byte, internal_cbyte, c_byteLength) != 0) { + LogError( "Computation of c in TPM DAA Join command is incorrect. Affected stages: 16,20\n"); + LogError( "\t c_byte[%d] %s", + c_byteLength, + dump_byte_array( c_byteLength, c_byte)); + LogError( "\tc_internal_byte[%d] %s", + internal_cbyteLength, + dump_byte_array( internal_cbyteLength, internal_cbyte)); + result = TSS_E_INTERNAL_ERROR; + goto close; + } + + // 5m) blind attributesReceiver + sa = (bi_array_ptr)malloc( sizeof( struct _bi_array)); + if( sa == NULL) { + LogError("malloc of %d bytes failed", sizeof( struct _bi_array)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_new_array( sa, attributesPlatformLength); + for( i=0; i < attributesPlatformLength; i++) { + attributePlatform = bi_set_as_nbin( DAA_PARAM_SIZE_F_I / 8, + attributesPlatform[i]); // allocation + if( attributePlatform == NULL) { + LogError("malloc of <bi> %s failed", "attributePlatform"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + LogDebug("calculating sa[%d]: raLength=%ld cLength=%ld attributesPlatformLength=%ld\n", + i, bi_nbin_size( ra->array[i]), bi_nbin_size( c), bi_nbin_size( attributePlatform)); + bi_add( sa->array[i], ra->array[i], bi_mul( tmp1, c, attributePlatform)); + bi_free_ptr( attributePlatform); + } + attributePlatform = NULL; + // 5o) Commitments + // TODO + + result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA, + 21, + 0, NULL, + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + LogDebug("Done Join 21: return sv_prime2"); + sv_prime2 = bi_set_as_nbin( outputSize, outputData); // allocation + if( sv_prime2 == NULL) { + LogError("malloc of <bi> %s failed", "sv_prime2"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + free( outputData); + sv_prime = bi_new_ptr(); + if( sv_prime == NULL) { + LogError("malloc of <bi> %s failed", "sv_prime"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + // sv_prime = sv_prime2 << DAA_PARAM_SIZE_SPLIT_EXPONENT + bi_shift_left( sv_prime, sv_prime2, DAA_PARAM_SIZE_SPLIT_EXPONENT); + // sv_prime = sv_prime + sv_prime1 + bi_add( sv_prime, sv_prime, sv_prime1); + + sv_tilde_prime = bi_new_ptr(); + // tmp1 = c * v_tilde_prime + bi_mul( tmp1, c, v_tilde_prime); + // sv_tilde_prime = rv_tilde_prime + tmp1 + bi_add( sv_tilde_prime, rv_tilde_prime, tmp1); + + // step 6) - choose nonce + bi_urandom( tmp1, DAA_PARAM_SAFETY_MARGIN * 8); + noncePlatform = (BYTE *)calloc_tspi( tcsContext, DAA_PARAM_SAFETY_MARGIN); + if( noncePlatform == NULL) { + LogError("malloc of <bi> %s failed", "noncePlatform"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &noncePlatformLength, noncePlatform, tmp1); + + LogDebug("challenge:%s", dump_byte_array( c_byteLength, c_byte)); + LogDebug("sF0 [%ld]:%s", bi_length( s_f0), bi_2_hex_char( s_f0)); + LogDebug("sF1 [%ld]:%s", bi_length( s_f1), bi_2_hex_char( s_f1)); + LogDebug("sv_prime [%ld]:%s", bi_length( sv_prime), bi_2_hex_char( sv_prime)); + LogDebug("sv_tilde_prime [%ld]:%s", bi_length( sv_tilde_prime), bi_2_hex_char( sv_tilde_prime)); + // update joinSession + joinSession->capitalU = calloc_tspi( tcsContext, bi_nbin_size( capitalU)); + if( joinSession->capitalU == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( capitalU)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(joinSession->capitalULength), + joinSession->capitalU, + capitalU); + joinSession->attributesPlatformLength = attributesPlatformLength; + joinSession->attributesPlatform = calloc_tspi( tcsContext, sizeof(BYTE *)); + for( i=0; i<joinSession->attributesPlatformLength; i++) { + joinSession->attributesPlatform[i] = + calloc_tspi( tcsContext,DAA_PARAM_SIZE_F_I / 8); + memcpy( joinSession->attributesPlatform[i], + attributesPlatform[i], + DAA_PARAM_SIZE_F_I / 8); + } + joinSession->noncePlatform = noncePlatform; + joinSession->noncePlatformLength = noncePlatformLength; + joinSession->vTildePrime = calloc_tspi( tcsContext, bi_nbin_size( v_tilde_prime)); + if( joinSession->vTildePrime == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( v_tilde_prime)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(joinSession->vTildePrimeLength), + joinSession->vTildePrime, + v_tilde_prime); + // update credentialRequest + credentialRequest->capitalU = calloc_tspi( tcsContext, bi_nbin_size( capitalU)); + if( credentialRequest->capitalU == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( capitalU)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(credentialRequest->capitalULength), + credentialRequest->capitalU, + capitalU); + credentialRequest->capitalNi = calloc_tspi( tcsContext, bi_nbin_size( capital_ni)); + if( credentialRequest->capitalNi == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( capital_ni)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(credentialRequest->capitalNiLength), + credentialRequest->capitalNi, + capital_ni); + credentialRequest->authenticationProofLength = authentication_proofLength; + credentialRequest->authenticationProof = authentication_proof; + credentialRequest->challenge = c_byte; + credentialRequest->challengeLength = c_byteLength; + credentialRequest->nonceTpm = nonce_tpm; + credentialRequest->nonceTpmLength = nonce_tpmLength; + credentialRequest->noncePlatform = noncePlatform; + credentialRequest->noncePlatformLength = DAA_PARAM_SAFETY_MARGIN; + credentialRequest->sF0 = calloc_tspi( tcsContext, bi_nbin_size( s_f0)); + if( credentialRequest->sF0 == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( s_f0)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(credentialRequest->sF0Length), credentialRequest->sF0, s_f0); + credentialRequest->sF1 = calloc_tspi( tcsContext, bi_nbin_size( s_f1)); + if( credentialRequest->sF1 == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( s_f1)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(credentialRequest->sF1Length), credentialRequest->sF1, s_f1); + credentialRequest->sVprime = calloc_tspi( tcsContext, bi_nbin_size( sv_prime)); + if( credentialRequest->sVprime == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( sv_prime)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(credentialRequest->sVprimeLength), + credentialRequest->sVprime, + sv_prime); + credentialRequest->sVtildePrime = calloc_tspi( tcsContext, bi_nbin_size( sv_tilde_prime)); + if( credentialRequest->sVtildePrime == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( sv_tilde_prime)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(credentialRequest->sVtildePrimeLength), + credentialRequest->sVtildePrime, + sv_tilde_prime); + length = (DAA_PARAM_SIZE_RANDOMIZED_ATTRIBUTES + 7) / 8; + LogDebug("SA length=%d", sa->length); + credentialRequest->sA = calloc_tspi( tcsContext, sizeof( BYTE *) * sa->length); + if( credentialRequest->sA == NULL) { + LogError("malloc of %d bytes failed", sizeof( BYTE *) * sa->length); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + + for( i=0; i<(UINT32)sa->length; i++) { + LogDebug("sa[%d].size=%d", i, (int)bi_nbin_size( sa->array[i])); + credentialRequest->sA[i] = calloc_tspi( tcsContext, length); + if( credentialRequest->sA[i] == NULL) { + LogError("malloc of %d bytes failed", length); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + // size used only as repository + bi_2_byte_array( credentialRequest->sA[i], length, sa->array[i]); + } + credentialRequest->sALength = sa->length; +close: + if( capitalSprime_byte_array!=NULL) free( capitalSprime_byte_array); + if( ch!=NULL) free( ch); + if( internal_cbyte != NULL) free( internal_cbyte); + bi_free_ptr( rv_tilde_prime); + bi_free_ptr( v_tilde_prime); + bi_free_ptr( capital_utilde); + bi_free_ptr( tmp1); + bi_free_ptr( tmp2); + bi_free_ptr( capitalU); + if( ra != NULL) { + bi_free_array( ra); + free( ra); + } + if( sa != NULL) { + bi_free_array( sa); + free( sa); + } + FREE_BI( capital_ni); + FREE_BI( capital_utilde_prime); + FREE_BI( capital_ni_tilde); + FREE_BI( n); + FREE_BI( attributePlatform); + FREE_BI( c); + FREE_BI( zeta); + FREE_BI( capital_Uprime); + FREE_BI( sv_tilde_prime); + FREE_BI( s_f0); + FREE_BI( s_f1); + FREE_BI( sv_prime); + FREE_BI( sv_prime1); + FREE_BI( sv_prime2); + FREE_BI( product_attributes); + free_TSS_DAA_PK_internal( pk_internal); + return result; +} + +/* +Code influenced by TSS.java (joinStoreCredential) +*/ +TSPICALL Tspi_TPM_DAA_JoinStoreCredential_internal +( + TSS_HDAA hDAA, // in + TSS_HTPM hTPM, // in + TSS_DAA_CRED_ISSUER credIssuer, // in + TSS_DAA_JOIN_SESSION joinSession, // in + TSS_HKEY* hDaaCredential // out +) { + TCS_CONTEXT_HANDLE tcsContext; + TPM_AUTH ownerAuth; + bi_ptr tmp1 = bi_new_ptr(); + bi_ptr tmp2 = bi_new_ptr(); + bi_ptr n = NULL; + bi_ptr e = NULL; + bi_ptr fraction_A = NULL; + bi_ptr v_prime_prime = NULL; + bi_ptr capital_U = NULL; + bi_ptr product_attributes = NULL; + bi_ptr capital_Atilde = NULL; + bi_ptr s_e = NULL; + bi_ptr c_prime = NULL; + bi_ptr capital_A = NULL; + bi_ptr product = NULL; + bi_ptr v_tilde_prime = NULL; + bi_ptr v_prime_prime0 = NULL; + bi_ptr v_prime_prime1 = NULL; + TSS_DAA_PK *daa_pk_extern; + TSS_DAA_PK_internal *pk_intern = NULL; + TSS_DAA_CREDENTIAL *daaCredential; + bi_array_ptr attributes_issuer; + TSS_RESULT result = TSS_SUCCESS; + UINT32 i; + UINT32 c_byteLength, v0Length, v1Length, tpm_specificLength; + BYTE *c_byte = NULL; + BYTE *v0 = NULL; + BYTE *v1 = NULL; + BYTE *tpm_specific = NULL; + + if( tmp1 == NULL || tmp2 == NULL) { + LogError("malloc of bi(s) failed"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + if( (result = obj_tpm_is_connected( hTPM, &tcsContext)) != TSS_SUCCESS) return result; + obj_daa_set_handle_tpm( hDAA, hTPM); + + LogDebug("Converting issuer public"); + daa_pk_extern = (TSS_DAA_PK *)joinSession.issuerPk; + pk_intern = e_2_i_TSS_DAA_PK( daa_pk_extern); + if( pk_intern == NULL) { + LogError("malloc of pk_intern failed"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + n = bi_new_ptr(); + if( n == NULL) { + LogError("malloc of bi <%s> failed", "n"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_set( n, pk_intern->modulus); + attributes_issuer = (bi_array_ptr)malloc( sizeof( struct _bi_array)); + if( attributes_issuer == NULL) { + LogError("malloc of %d bytes failed", sizeof( struct _bi_array)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_new_array( attributes_issuer, credIssuer.attributesIssuerLength); + if( attributes_issuer->array == NULL) { + LogError("malloc of bi_array <%s> failed", "attributes_issuer->array"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + for( i=0; i < credIssuer.attributesIssuerLength; i++) { + // allocation + attributes_issuer->array[i] = bi_set_as_nbin( DAA_PARAM_SIZE_F_I / 8, + credIssuer.attributesIssuer[i]); + if( attributes_issuer->array[i] == NULL) { + LogError("malloc of bi <attributes_issuer->array[%d]> failed", i); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + } + LogDebug("verify credential of issuer ( part 1)"); + e = bi_set_as_nbin( credIssuer.eLength, credIssuer.e); // allocation + if( e == NULL) { + LogError("malloc of bi <%s> failed", "e"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_set( tmp1, bi_0); + bi_setbit( tmp1, DAA_PARAM_SIZE_EXPONENT_CERTIFICATE - 1); + bi_set( tmp2, bi_0); + bi_setbit( tmp1, DAA_PARAM_SIZE_INTERVAL_EXPONENT_CERTIFICATE - 1); + bi_add( tmp1, tmp1, tmp2); + if( bi_is_probable_prime( e) == 0 || + bi_length(e) < DAA_PARAM_SIZE_EXPONENT_CERTIFICATE || + bi_cmp( e, tmp1) > 0) { + LogError("Verification e failed - Step 1.a"); + LogError("\tPrime(e):%d", bi_is_probable_prime( e)); + LogError("\tbit_length(e):%ld", bi_length(e)); + LogError("\te > (2^(l_e) + 2^(l_prime_e)):%d", bi_cmp( e, tmp1)); + result = TSS_E_DAA_CREDENTIAL_PROOF_ERROR; + goto close; + } + LogDebug("verify credential of issuer (part 2) with proof"); + fraction_A = bi_new_ptr(); + if( fraction_A == NULL) { + LogError("malloc of bi <%s> failed", "fraction_A"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + v_prime_prime = bi_set_as_nbin( credIssuer.vPrimePrimeLength, + credIssuer.vPrimePrime); // allocation + if( v_prime_prime == NULL) { + LogError("malloc of bi <%s> failed", "v_prime_prime"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + capital_U = bi_set_as_nbin( joinSession.capitalULength, + joinSession.capitalU); // allocation + if( capital_U == NULL) { + LogError("malloc of bi <%s> failed", "capital_U"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_mod_exp( fraction_A, pk_intern->capitalS, v_prime_prime, n); + bi_mul( fraction_A, fraction_A, capital_U); + bi_mod( fraction_A, fraction_A, n); + LogDebug("encode attributes"); + product_attributes = bi_new_ptr(); + bi_set( product_attributes, bi_1); + for( i=0; i<(UINT32)attributes_issuer->length; i++) { + bi_mod_exp( tmp1, pk_intern->capitalRIssuer->array[i], + attributes_issuer->array[i], n); + bi_mul( product_attributes, tmp1, product_attributes); + bi_mod( product_attributes, product_attributes, n); + } + bi_mul( fraction_A, fraction_A, product_attributes); + bi_mod( fraction_A, fraction_A, n); + capital_Atilde = bi_new_ptr(); + if( capital_Atilde == NULL) { + LogError("malloc of bi <%s> failed", "capital_Atilde"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_invert_mod( capital_Atilde, fraction_A, n); + bi_mul( capital_Atilde, capital_Atilde, pk_intern->capitalZ); + bi_mod( capital_Atilde, capital_Atilde, n); + s_e = bi_set_as_nbin( credIssuer.sELength, credIssuer.sE); // allocation + if( s_e == NULL) { + LogError("malloc of bi <%s> failed", "s_e"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_mod_exp( capital_Atilde, capital_Atilde, s_e, n); + c_prime = bi_set_as_nbin( credIssuer.cPrimeLength, credIssuer.cPrime); // allocation + if( c_prime == NULL) { + LogError("malloc of bi <%s> failed", "c_prime"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + capital_A = bi_set_as_nbin( credIssuer.capitalALength, credIssuer.capitalA); // allocation + if( capital_A == NULL) { + LogError("malloc of bi <%s> failed", "capital_A"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_mod_exp( tmp1, capital_A, c_prime, n); + bi_mul( capital_Atilde, capital_Atilde, tmp1); + bi_mod( capital_Atilde, capital_Atilde, n); + + result = compute_join_challenge_issuer( pk_intern, + v_prime_prime, + capital_A, + capital_Atilde, + joinSession.noncePlatformLength, + joinSession.noncePlatform, + &c_byteLength, + &c_byte); // out allocation + if( result != TSS_SUCCESS) goto close; + if( credIssuer.cPrimeLength != c_byteLength || + memcmp( credIssuer.cPrime, c_byte, c_byteLength)!=0) { + LogError("Verification of c failed - Step 1.c.i"); + LogError("credentialRequest.cPrime[%d]=%s", + credIssuer.cPrimeLength, + dump_byte_array( credIssuer.cPrimeLength, credIssuer.cPrime) ); + LogError("challenge[%d]=%s", + c_byteLength, + dump_byte_array( c_byteLength, c_byte) ); + result = TSS_E_DAA_CREDENTIAL_PROOF_ERROR; + goto close; + } + product = bi_new_ptr(); + if( product == NULL) { + LogError("malloc of bi <%s> failed", "product"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_mod_exp( product, capital_A, e, n); + bi_mul( product, product, fraction_A); + bi_mod( product, product, n); + if( bi_equals( pk_intern->capitalZ, product) == 0) { + LogError("Verification of A failed - Step 1.c.ii"); + LogError("\tcapitalZ=%s", bi_2_hex_char( pk_intern->capitalZ)); + LogError("\tproduct=%s", bi_2_hex_char( product)); + result = TSS_E_DAA_CREDENTIAL_PROOF_ERROR; + goto close; + } + v_tilde_prime = bi_set_as_nbin( joinSession.vTildePrimeLength, + joinSession.vTildePrime); // allocation + bi_add( v_prime_prime, v_prime_prime, v_tilde_prime); + bi_shift_left( tmp1, bi_1, DAA_PARAM_SIZE_SPLIT_EXPONENT); + v_prime_prime0 = bi_new_ptr(); + if( v_prime_prime0 == NULL) { + LogError("malloc of bi <%s> failed", "v_prime_prime0"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_mod( v_prime_prime0, v_prime_prime, tmp1); + v_prime_prime1 = bi_new_ptr(); + if( v_prime_prime1 == NULL) { + LogError("malloc of bi <%s> failed", "v_prime_prime1"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_shift_right( v_prime_prime1, v_prime_prime, DAA_PARAM_SIZE_SPLIT_EXPONENT); + free( c_byte); + c_byte = (BYTE *)malloc( TPM_DAA_SIZE_v0); + if( c_byte == NULL) { + LogError("malloc of %d bytes failed", TPM_DAA_SIZE_v0); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_byte_array( c_byte, TPM_DAA_SIZE_v0, v_prime_prime0); + result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA, + 22, + TPM_DAA_SIZE_v0, c_byte, + 0, NULL, + &ownerAuth, &v0Length, &v0); + if( result != TSS_SUCCESS) goto close; + LogDebug("Done Join 22: return v0"); + free( c_byte); + c_byte = (BYTE *)malloc( TPM_DAA_SIZE_v1); + if( c_byte == NULL) { + LogError("malloc of %d bytes failed", TPM_DAA_SIZE_v1); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_byte_array( c_byte, TPM_DAA_SIZE_v1, v_prime_prime1); + result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA, + 23, + TPM_DAA_SIZE_v1, c_byte, + 0, NULL, + &ownerAuth, &v1Length, &v1); + if( result != TSS_SUCCESS) goto close; + LogDebug("Done Join 23: return v1"); + result = Tcsip_TPM_DAA_Join_encapsulate( tcsContext, hDAA, + 24, + 0, NULL, + 0, NULL, + &ownerAuth, &tpm_specificLength, &tpm_specific); + if( result != TSS_SUCCESS) goto close; + + daaCredential = (TSS_DAA_CREDENTIAL *)hDaaCredential; + daaCredential->capitalA = calloc_tspi( tcsContext, bi_nbin_size( capital_A)); + if( daaCredential->capitalA == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( capital_A)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(daaCredential->capitalALength), daaCredential->capitalA, capital_A); + daaCredential->exponent = calloc_tspi( tcsContext, bi_nbin_size( e)); + if( daaCredential->exponent == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( e)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(daaCredential->exponentLength), daaCredential->exponent, e); + daaCredential->vBar0 = calloc_tspi( tcsContext, v0Length); + if( daaCredential->vBar0 == NULL) { + LogError("malloc of %d bytes failed", v0Length); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + daaCredential->vBar0Length = v0Length; + memcpy( daaCredential->vBar0, v0, v0Length); + LogDebug("vBar0[%d]=%s", + daaCredential->vBar0Length, + dump_byte_array( daaCredential->vBar0Length, daaCredential->vBar0)); + daaCredential->vBar1 = calloc_tspi( tcsContext, v1Length); + if( daaCredential->vBar1 == NULL) { + LogError("malloc of %d bytes failed", v1Length); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + daaCredential->vBar1Length = v1Length; + memcpy( daaCredential->vBar1, v1, v1Length); + LogDebug("vBar1[%d]=%s", + daaCredential->vBar1Length, + dump_byte_array( daaCredential->vBar1Length, daaCredential->vBar1)); + //TODO remove + LogDebug("[BUSS] joinSession.attributesPlatformLength=%d", + joinSession.attributesPlatformLength); + LogDebug("[BUSS] credIssuer.attributesIssuerLength=%d", + credIssuer.attributesIssuerLength); + daaCredential->attributesLength = joinSession.attributesPlatformLength + + credIssuer.attributesIssuerLength; + daaCredential->attributes = (BYTE **)calloc_tspi( tcsContext, + sizeof(BYTE *) * daaCredential->attributesLength); + if( daaCredential->attributes == NULL) { + LogError("malloc of %d bytes failed", + sizeof(BYTE *) * daaCredential->attributesLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + for( i=0; i < joinSession.attributesPlatformLength; i++) { + daaCredential->attributes[i] = calloc_tspi( tcsContext, DAA_PARAM_SIZE_F_I / 8); + if( daaCredential->attributes[i] == NULL) { + LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_F_I / 8); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + LogDebug("allocation attributes[%d]=%lx", i, (long)daaCredential->attributes[i]); + memcpy( daaCredential->attributes[i], + joinSession.attributesPlatform[i], + DAA_PARAM_SIZE_F_I / 8); + } + for( i=0; i < credIssuer.attributesIssuerLength; i++) { + daaCredential->attributes[i+joinSession.attributesPlatformLength] = + calloc_tspi( tcsContext, DAA_PARAM_SIZE_F_I / 8); + if( daaCredential->attributes[i+joinSession.attributesPlatformLength] == NULL) { + LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_F_I / 8); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + memcpy( daaCredential->attributes[i+joinSession.attributesPlatformLength], + credIssuer.attributesIssuer[i], DAA_PARAM_SIZE_F_I / 8); + } + memcpy( &(daaCredential->issuerPK), daa_pk_extern, sizeof( TSS_DAA_PK)); + daaCredential->tpmSpecificEnc = calloc_tspi( tcsContext, tpm_specificLength); + if( daaCredential->tpmSpecificEnc == NULL) { + LogError("malloc of %d bytes failed", tpm_specificLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + daaCredential->tpmSpecificEncLength = tpm_specificLength; + memcpy( daaCredential->tpmSpecificEnc, tpm_specific, tpm_specificLength); + // TODO store in TSS this TSS_DAA_CREDENTIAL_REQUEST + *hDaaCredential = (TSS_HKEY)daaCredential; +close: + if( v0 != NULL) free( v0); + if( v1 != NULL) free( v1); + if( tpm_specific != NULL) free( tpm_specific); + if( c_byte != NULL) free( c_byte); + bi_free_ptr( tmp2); + bi_free_ptr( tmp1); + if( attributes_issuer != NULL) { + bi_free_array( attributes_issuer); + free( attributes_issuer); + } + FREE_BI( v_prime_prime1); + FREE_BI( v_prime_prime0); + FREE_BI( v_tilde_prime); + FREE_BI( product); + FREE_BI( capital_A); + FREE_BI( c_prime); + FREE_BI( s_e); + FREE_BI( capital_Atilde); + FREE_BI( product_attributes); + FREE_BI( capital_U); + FREE_BI( v_prime_prime); + FREE_BI( fraction_A); + FREE_BI( e); + FREE_BI( n); + if( pk_intern!=NULL) free_TSS_DAA_PK_internal( pk_intern); + return result; +} + +static void add_splitet( bi_ptr result, bi_ptr a, bi_ptr b) { + bi_shift_left( result, bi_1, DAA_PARAM_SIZE_SPLIT_EXPONENT); + bi_mul( result, result, b); + bi_add( result, result, a); +} + +/* code influenced by TSS.java (signStep) */ +TSS_RESULT Tspi_TPM_DAA_Sign_internal +( + TSS_HDAA hDAA, // in + TSS_HTPM hTPM, // in + TSS_HKEY hDaaCredential, // in + TSS_DAA_SELECTED_ATTRIB revealAttributes, // in + UINT32 verifierBaseNameLength, // in + BYTE* verifierBaseName, // in + UINT32 verifierNonceLength, // in + BYTE* verifierNonce, // in + TSS_DAA_SIGN_DATA signData, // in + TSS_DAA_SIGNATURE* daaSignature // out +) +{ + TCS_CONTEXT_HANDLE tcsContext; + TSS_DAA_CREDENTIAL *daaCredential; + TPM_DAA_ISSUER *tpm_daa_issuer; + TPM_AUTH ownerAuth; + TSS_RESULT result = TSS_SUCCESS; + TSS_DAA_PK *pk; + TSS_DAA_PK_internal *pk_intern; + int i; + bi_ptr tmp1 = bi_new_ptr(), tmp2; + bi_ptr n = NULL; + bi_ptr capital_gamma = NULL; + bi_ptr gamma = NULL; + bi_ptr zeta = NULL; + bi_ptr r = NULL; + bi_ptr t_tilde_T = NULL; + bi_ptr capital_Nv = NULL; + bi_ptr capital_N_tilde_v = NULL; + bi_ptr w = NULL; + bi_ptr capital_T = NULL; + bi_ptr r_E = NULL; + bi_ptr r_V = NULL; + bi_ptr capital_T_tilde = NULL; + bi_ptr capital_A = NULL; + bi_array_ptr capital_R; + bi_ptr product_R = NULL; + bi_array_ptr r_A = NULL; + bi_array_ptr s_A = NULL; + bi_ptr c = NULL; + bi_ptr sF0 = NULL; + bi_ptr sF1 = NULL; + bi_ptr sV1 = NULL; + bi_ptr sV2 = NULL; + bi_ptr e = NULL; + bi_ptr s_E = NULL; + bi_ptr s_V = NULL; + CS_ENCRYPTION_RESULT_RANDOMNESS *encryption_result_rand = NULL; + BYTE *issuer_settings = NULL, *outputData, byte; + BYTE *buffer = NULL, *ch = NULL, *nonce_tpm = NULL, *c_bytes = NULL; + UINT32 issuer_settingsLength, outputSize, length, size_bits, chLength; + UINT32 nonce_tpmLength; + UINT32 c_bytesLength, return_sign_session; + // for anonymity revocation + CS_ENCRYPTION_RESULT *encryption_result = NULL; + CS_ENCRYPTION_RESULT *encryption_result_tilde = NULL; + TSS_DAA_PSEUDONYM *signature_pseudonym; + TSS_DAA_PSEUDONYM_PLAIN *pseudonym_plain = NULL; + TSS_DAA_PSEUDONYM_PLAIN *pseudonym_plain_tilde = NULL; + TSS_DAA_ATTRIB_COMMIT *signed_commitments; + + if( (result = obj_tpm_is_connected( hTPM, &tcsContext)) != TSS_SUCCESS) + return result; + if( tmp1 == NULL) { + LogError("malloc of bi <%s> failed", "tmp1"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + obj_daa_set_handle_tpm( hDAA, hTPM); + // TODO retrieve the daaCredential from the persistence storage + daaCredential = (TSS_DAA_CREDENTIAL *)hDaaCredential; + pk = (TSS_DAA_PK *)&(daaCredential->issuerPK); + pk_intern = e_2_i_TSS_DAA_PK( pk); + if( pk_intern == NULL) { + LogError("malloc of <%s> failed", "pk_intern"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + tpm_daa_issuer = convert2issuer_settings( pk_intern); + if( daaCredential->attributesLength == 0 || + daaCredential->attributesLength != revealAttributes.indicesListLength) { + LogDebug("Problem with the reveal attribs: attributes length:%d reveal length:%d", + daaCredential->attributesLength, revealAttributes.indicesListLength); + result = TSS_E_BAD_PARAMETER; + goto close; + } + if( verifierNonce == NULL || + verifierNonceLength != DAA_PARAM_LENGTH_MESSAGE_DIGEST) { + LogDebug("Problem with the nonce verifier: nonce verifier length:%d", + verifierNonceLength); + result = TSS_E_BAD_PARAMETER; + goto close; + } + n = bi_new_ptr(); + if( n == NULL) { + LogError("malloc of bi <%s> failed", "n"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_set( n, pk_intern->modulus); + capital_gamma = bi_new_ptr(); + if( capital_gamma == NULL) { + LogError("malloc of bi <%s> failed", "capital_gamma"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_set( capital_gamma, pk_intern->capitalGamma); + gamma = bi_new_ptr(); + if( gamma == NULL) { + LogError("malloc of bi <%s> failed", "gamma"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_set( gamma, pk_intern->gamma); + if( verifierBaseNameLength == 0 || verifierBaseName == NULL) { + r = bi_new_ptr(); + compute_random_number( r, capital_gamma); + zeta = project_into_group_gamma( r, pk_intern); // allocation + if( zeta == NULL) { + LogError("malloc of bi <%s> failed", "zeta"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + } else { + zeta = compute_zeta( verifierBaseNameLength, verifierBaseName, pk_intern); + if( zeta == NULL) { + LogError("malloc of bi <%s> failed", "zeta"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + } + issuer_settings = issuer_2_byte_array( tpm_daa_issuer, + &issuer_settingsLength); // allocation + if( issuer_settings == NULL) { + LogError("malloc of %d bytes failed", issuer_settingsLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + LogDebug( "Issuer Settings:[%s]", + dump_byte_array(issuer_settingsLength, issuer_settings) ); + result = Tcsip_TPM_DAA_Sign( + tcsContext, hDAA, + 0, + issuer_settingsLength, issuer_settings, + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + // set the sessionHandle to the returned value + return_sign_session = ntohl( *((UINT32 *)outputData)); + obj_daa_set_session_handle( hDAA, return_sign_session); + free( outputData); + result = Tcsip_TPM_DAA_Sign( + tcsContext, hDAA, + 1, + daaCredential->tpmSpecificEncLength, daaCredential->tpmSpecificEnc, + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + free( outputData); + LogDebug( "done Sign 1 - TPM specific"); + result = Tcsip_TPM_DAA_Sign( + tcsContext, hDAA, + 2, + pk->capitalR0Length, pk->capitalR0, + pk->modulusLength, pk->modulus, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + free( outputData); + LogDebug( "done Sign 2 - capitalR0"); + result = Tcsip_TPM_DAA_Sign( + tcsContext, hDAA, + 3, + pk->capitalR1Length, pk->capitalR1, + pk->modulusLength, pk->modulus, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + free( outputData); + LogDebug( "done Sign 3 - capitalR1"); + result = Tcsip_TPM_DAA_Sign( + tcsContext, hDAA, + 4, + pk->capitalSLength, pk->capitalS, + pk->modulusLength, pk->modulus, + &ownerAuth, &outputSize, &outputData); + if( outputSize > 0 && outputData != NULL) free( outputData); + if( result != TSS_SUCCESS) goto close; + LogDebug( "done Sign 4 - capitalS"); + buffer = bi_2_nbin( &length, pk_intern->capitalSprime); // allocation + if( buffer == NULL) { + LogError("malloc of %d bytes failed", length); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + result = Tcsip_TPM_DAA_Sign( + tcsContext, hDAA, + 5, + length, buffer, + pk->modulusLength, pk->modulus, + &ownerAuth, &outputSize, &outputData); + free( buffer); + if( result != TSS_SUCCESS) goto close; + LogDebug( "done Sign 5 - capitalSPrime. Return t_tilde_T"); + t_tilde_T = bi_set_as_nbin( outputSize, outputData); // allocation + if( t_tilde_T == NULL) { + LogError("malloc of bi <%s> failed", "t_tilde_T"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + free( outputData); + // first precomputation until here possible (verifier independent) + length = TPM_DAA_SIZE_w; + buffer = (BYTE *)malloc( length); + if( buffer == NULL) { + LogError("malloc of %d bytes failed", length); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_byte_array( buffer, length, zeta); + result = Tcsip_TPM_DAA_Sign( + tcsContext, hDAA, + 6, + pk->capitalGammaLength, pk->capitalGamma, + length, buffer, + &ownerAuth, &outputSize, &outputData); + free( buffer); + if( result != TSS_SUCCESS) goto close; + LogDebug( "done Sign 6 - capitalGamma & zeta"); + result = Tcsip_TPM_DAA_Sign( + tcsContext, hDAA, + 7, + pk->capitalGammaLength, pk->capitalGamma, + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + LogDebug( "done Sign 7 - capitalGamma. Return capital_Nv"); + capital_Nv = bi_set_as_nbin( outputSize, outputData); // allocation + if( capital_Nv == NULL) { + LogError("malloc of bi <%s> failed", "capital_Nv"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + free( outputData); + // TODO Step 6 a.b - anonymity revocation + + result = Tcsip_TPM_DAA_Sign( + tcsContext, hDAA, + 8, + pk->capitalGammaLength, pk->capitalGamma, + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + LogDebug( "done Sign 8 - capitalGamma. Return capital_N_tilde_v"); + capital_N_tilde_v = bi_set_as_nbin( outputSize, outputData); // allocation + if( capital_N_tilde_v == NULL) { + LogError("malloc of bi <%s> failed", "capital_N_tilde_v"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + free( outputData); + // TODO Step 6 c,d - anonymity revocation + + // Second precomputation until here possible (verifier dependent) + size_bits = DAA_PARAM_SIZE_RSA_MODULUS + DAA_PARAM_SAFETY_MARGIN; + w = bi_new_ptr(); + if( w == NULL) { + LogError("malloc of bi <%s> failed", "w"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_urandom( w, size_bits); + capital_A = bi_set_as_nbin( daaCredential->capitalALength, + daaCredential->capitalA); // allocation + if( capital_A == NULL) { + LogError("malloc of bi <%s> failed", "capital_A"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + capital_T = bi_new_ptr(); + if( capital_T == NULL) { + LogError("malloc of bi <%s> failed", "capital_T"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_mod_exp( tmp1, pk_intern->capitalS, w, n); + bi_mul( capital_T, capital_A, tmp1); + bi_mod( capital_T, capital_T, n); + size_bits = DAA_PARAM_SIZE_INTERVAL_EXPONENT_CERTIFICATE + + DAA_PARAM_SAFETY_MARGIN + DAA_PARAM_SIZE_MESSAGE_DIGEST; + r_E = bi_new_ptr(); + if( r_E == NULL) { + LogError("malloc of bi <%s> failed", "r_E"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_urandom( r_E, size_bits); + size_bits = DAA_PARAM_SIZE_EXPONENT_CERTIFICATE + DAA_PARAM_SIZE_RSA_MODULUS + + 2 * DAA_PARAM_SAFETY_MARGIN + DAA_PARAM_SIZE_MESSAGE_DIGEST + 1; + r_V = bi_new_ptr(); + if( r_V == NULL) { + LogError("malloc of bi <%s> failed", "r_V"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_urandom( r_V, size_bits); + capital_T_tilde = bi_new_ptr(); + if( capital_T_tilde == NULL) { + LogError("malloc of bi <%s> failed", "capital_T_tilde"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_mod_exp( tmp1, capital_T, r_E, n); + bi_mul( capital_T_tilde, t_tilde_T, tmp1); + bi_mod( capital_T_tilde, capital_T_tilde, n); + + bi_mod_exp( tmp1, pk_intern->capitalS, r_V, n); + bi_mul( capital_T_tilde, capital_T_tilde, tmp1); + bi_mod( capital_T_tilde, capital_T_tilde, n); + + // attributes extension + size_bits = DAA_PARAM_SIZE_F_I + + DAA_PARAM_SAFETY_MARGIN + + DAA_PARAM_SIZE_MESSAGE_DIGEST; + capital_R = pk_intern->capitalY; + r_A = (bi_array_ptr)malloc( sizeof( struct _bi_array)); + if( r_A == NULL) { + LogError("malloc of %d bytes failed", sizeof( struct _bi_array)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_new_array2( r_A, revealAttributes.indicesListLength); + product_R = bi_new_ptr(); + if( product_R == NULL) { + LogError("malloc of bi <%s> failed", "product_R"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_set( product_R, bi_1); + for( i=0; i<(int)revealAttributes.indicesListLength; i++) { + if( revealAttributes.indicesList[i] == 0) { + // only non selected + r_A->array[i] = bi_new_ptr(); + if( r_A->array[i] == NULL) { + LogError("malloc of bi <%s> failed", "r_A->array[i]"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_urandom( r_A->array[i] , size_bits); + bi_mod_exp( tmp1, capital_R->array[i], r_A->array[i], n); + bi_mul( product_R, product_R, tmp1); + bi_mod( product_R, product_R, n); + } else r_A->array[i] = NULL; + } + bi_mul( capital_T_tilde, capital_T_tilde, product_R); + bi_mod( capital_T_tilde, capital_T_tilde, n); + //TODO Step 8 - Commitments + // compute commitment to attributes not revealed to the verifier + + //TODO Step 9 - callback functions + + // only when revocation not enabled + pseudonym_plain = (TSS_DAA_PSEUDONYM_PLAIN *)calloc_tspi( tcsContext, + sizeof(TSS_DAA_PSEUDONYM_PLAIN)); + if( pseudonym_plain == NULL) { + LogError("malloc of %d bytes failed", sizeof(TSS_DAA_PSEUDONYM_PLAIN)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + init_tss_version( pseudonym_plain); + pseudonym_plain->capitalNv = calloc_tspi( tcsContext, + bi_nbin_size( capital_Nv)); + if( pseudonym_plain->capitalNv == NULL) { + LogError("malloc of bi <%s> failed", "pseudonym_plain->capitalNv"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(pseudonym_plain->capitalNvLength), + pseudonym_plain->capitalNv, + capital_Nv); + pseudonym_plain_tilde = (TSS_DAA_PSEUDONYM_PLAIN *) + calloc_tspi( tcsContext,sizeof(TSS_DAA_PSEUDONYM_PLAIN)); + if( pseudonym_plain_tilde == NULL) { + LogError("malloc of %d bytes failed", sizeof(TSS_DAA_PSEUDONYM_PLAIN)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + init_tss_version( pseudonym_plain_tilde); + pseudonym_plain_tilde->capitalNv = calloc_tspi( tcsContext, + bi_nbin_size( capital_N_tilde_v)); + if( pseudonym_plain_tilde->capitalNv == NULL) { + LogError("malloc of bi <%s> failed", "pseudonym_plain_tilde->capitalNv"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(pseudonym_plain_tilde->capitalNvLength), + pseudonym_plain_tilde->capitalNv, + capital_N_tilde_v); + + // Step 10 - compute challenge + ch = compute_sign_challenge_host( + &chLength, + DAA_PARAM_get_message_digest(), + pk_intern, + verifierNonceLength, + verifierNonce, + 0, // int selected_attributes2commitLength, + NULL, // TSS_DAA_SELECTED_ATTRIB **selected_attributes2commit, + 0, // int is_anonymity_revocation_enabled, + zeta, + capital_T, + capital_T_tilde, + 0, // int attribute_commitmentsLength, + NULL, // TSS_DAA_ATTRIB_COMMIT_internal **attribute_commitments, + NULL, // TSS_DAA_ATTRIB_COMMIT_internal **attribute_commitment_proofs, + capital_Nv, + capital_N_tilde_v, + NULL, // CS_PUBLIC_KEY *anonymity_revocator_pk, + NULL, // CS_ENCRYPTION_RESULT *encryption_result_rand, + NULL //CS_ENCRYPTION_RESULT *encryption_result_proof) + ); + if( ch == NULL) { + LogError("malloc in compute_sign_challenge_host failed"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + result = Tcsip_TPM_DAA_Sign( tcsContext, hDAA, + 9, + chLength, ch, + 0, NULL, + &ownerAuth, &nonce_tpmLength, &nonce_tpm); + if( result != TSS_SUCCESS) goto close; + LogDebug( "done Sign 9 - compute sign challenge host. Return nonce_tpm"); + byte = (BYTE)signData.payloadFlag; // 0 -> payload contains a handle to an AIK + // 1 -> payload contains a hashed message + result = Tcsip_TPM_DAA_Sign( tcsContext, hDAA, + 10, + sizeof(BYTE), &byte, + signData.payloadLength, signData.payload, + &ownerAuth, &c_bytesLength, &c_bytes); + LogDebug("calculation of c: ch[%d]%s", chLength, dump_byte_array( chLength, ch)); + LogDebug("calculation of c: nonce_tpm[%d]%s", + nonce_tpmLength, + dump_byte_array( nonce_tpmLength, nonce_tpm)); + LogDebug("calculation of c: sign_data.payloadFlag[%d]%x", + 1, + (int)signData.payloadFlag); + LogDebug("calculation of c: signdata.payload[%d]%s", + signData.payloadLength, + dump_byte_array( signData.payloadLength, signData.payload)); + + if( result != TSS_SUCCESS) goto close; + LogDebug( "done Sign 10 - compute signData.payload."); + LogDebug(" Return c_bytes[%d]%s", + c_bytesLength, + dump_byte_array( c_bytesLength, c_bytes)); + c = bi_set_as_nbin( c_bytesLength, c_bytes); // allocation + if( c == NULL) { + LogError("malloc of bi <%s> failed", "c"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + result = Tcsip_TPM_DAA_Sign( + tcsContext, hDAA, + 11, + 0, NULL, + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS)goto close; + LogDebug( "done Sign 11. Return sF0"); + sF0 = bi_set_as_nbin( outputSize, outputData); // allocation + if( sF0 == NULL) { + LogError("malloc of bi <%s> failed", "sF0"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + free( outputData); + result = Tcsip_TPM_DAA_Sign( + tcsContext, hDAA, + 12, + 0, NULL, + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + LogDebug( "done Sign 12. Return sF1"); + sF1 = bi_set_as_nbin( outputSize, outputData); // allocation + if( sF1 == NULL) { + LogError("malloc of bi <%s> failed", "sF1"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + free( outputData); + result = Tcsip_TPM_DAA_Sign( + tcsContext, hDAA, + 13, + daaCredential->vBar0Length, daaCredential->vBar0, + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + LogDebug( "done Sign 13. Return sV1"); + sV1 = bi_set_as_nbin( outputSize, outputData); // allocation + if( sV1 == NULL) { + LogError("malloc of bi <%s> failed", "sV1"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + free( outputData); + result = Tcsip_TPM_DAA_Sign( + tcsContext, hDAA, + 14, + daaCredential->vBar0Length, daaCredential->vBar0, + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + free( outputData); + LogDebug( "done Sign 14."); + result = Tcsip_TPM_DAA_Sign( + tcsContext, hDAA, + 15, + daaCredential->vBar1Length, daaCredential->vBar1, + 0, NULL, + &ownerAuth, &outputSize, &outputData); + if( result != TSS_SUCCESS) goto close; + LogDebug( "done Sign 15. Return sV2"); + sV2 = bi_set_as_nbin( outputSize, outputData); // allocation + if( sV2 == NULL) { + LogError("malloc of bi <%s> failed", "sV2"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + free( outputData); + // allocation + e = bi_set_as_nbin( daaCredential->exponentLength, daaCredential->exponent); + if( e == NULL) { + LogError("malloc of bi <%s> failed", "e"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + // s_e = r_E + ( c * ( e - ( 1 << (sizeExponentCertificate -1)))) + s_E = bi_new_ptr(); + if( s_E == NULL) { + LogError("malloc of bi <%s> failed", "s_E"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_shift_left( tmp1, bi_1, DAA_PARAM_SIZE_EXPONENT_CERTIFICATE - 1); + bi_sub( tmp1, e, tmp1); + bi_mul( tmp1, c, tmp1); + bi_add( s_E, r_E, tmp1); + s_V = bi_new_ptr(); + if( s_V == NULL) { + LogError("malloc of bi <%s> failed", "s_V"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + add_splitet( s_V, sV1, sV2); + bi_add( s_V, s_V, r_V); + bi_mul( tmp1, c, w); + bi_mul( tmp1, tmp1, e); + bi_sub( s_V, s_V, tmp1); + // attributes extension + // TODO verify the size of each selected attributes + s_A = (bi_array_ptr)malloc( sizeof( struct _bi_array)); + if( s_A == NULL) { + LogError("malloc of bi_array <%s> failed", "s_A"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_new_array2( s_A, revealAttributes.indicesListLength); + if( s_A->array == NULL) { + LogError("malloc of bi_array <%s> failed", "s_A"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + for( i=0; i<(int)revealAttributes.indicesListLength; i++) { + if( revealAttributes.indicesList[i] == 0) { + s_A->array[i] = bi_new_ptr(); + if( s_A->array[i] == NULL) { + LogError("malloc of bi <%s> failed", "s_A->array[i]"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + tmp2 = bi_set_as_nbin( DAA_PARAM_SIZE_F_I / 8, + daaCredential->attributes[i]); // allocation + if( tmp2 == NULL) { + LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_F_I / 8); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_mul( tmp1, c, tmp2); + // TODEL + LogDebug("daaCredential->attributes[i]=%ld", bi_nbin_size( tmp2)); + LogDebug("r_A:%ld", bi_nbin_size( r_A->array[i])); + LogDebug("c:%ld", bi_nbin_size( c)); + LogDebug("c*daaCredential->attributes[i]=%ld", bi_nbin_size( tmp1)); + // END TODEL + bi_add( s_A->array[i], r_A->array[i], tmp1); + bi_free_ptr( tmp2); + } else s_A->array[i] = NULL; + } + + // Compose result structure + + // DAASignaturePseudonym TODO: implement anonymity revocation + // if ( !revocation_enabled) + signature_pseudonym = pseudonym_plain; + + // populate the signature (TSS_DAA_SIGNATURE) + daaSignature->zeta = (BYTE *)calloc_tspi( tcsContext, bi_nbin_size( zeta)); + if (daaSignature->zeta == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( zeta)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(daaSignature->zetaLength), daaSignature->zeta, zeta); + daaSignature->capitalT = (BYTE *)calloc_tspi( tcsContext, bi_nbin_size( capital_T)); + if (daaSignature->capitalT == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( capital_T)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(daaSignature->capitalTLength), daaSignature->capitalT, capital_T); + daaSignature->challenge = (BYTE *)calloc_tspi( tcsContext, c_bytesLength); + if (daaSignature->challenge == NULL) { + LogError("malloc of %d bytes failed", c_bytesLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + daaSignature->challengeLength = c_bytesLength; + memcpy( daaSignature->challenge, c_bytes, c_bytesLength); + daaSignature->nonceTpm = (BYTE *)calloc_tspi( tcsContext, nonce_tpmLength); + if (daaSignature->nonceTpm == NULL) { + LogError("malloc of %d bytes failed", nonce_tpmLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + daaSignature->nonceTpmLength = nonce_tpmLength; + memcpy( daaSignature->nonceTpm, nonce_tpm, nonce_tpmLength); + daaSignature->sV = (BYTE *)calloc_tspi( tcsContext, bi_nbin_size( s_V)); + if (daaSignature->sV == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( s_V)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(daaSignature->sVLength), daaSignature->sV, s_V); + daaSignature->sF0 = (BYTE *)calloc_tspi( tcsContext, bi_nbin_size( sF0)); + if (daaSignature->sF0 == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( sF0)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(daaSignature->sF0Length), daaSignature->sF0, sF0); + daaSignature->sF1 = (BYTE *)calloc_tspi( tcsContext, bi_nbin_size( sF1)); + if (daaSignature->sF1 == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( sF1)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(daaSignature->sF1Length), daaSignature->sF1, sF1); + daaSignature->sE = (BYTE *)calloc_tspi( tcsContext, bi_nbin_size( s_E)); + if (daaSignature->sE == NULL) { + LogError("malloc of %ld bytes failed", bi_nbin_size( s_E)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_2_nbin1( &(daaSignature->sELength), daaSignature->sE, s_E); + daaSignature->sALength = revealAttributes.indicesListLength; + daaSignature->sA = (BYTE **)calloc_tspi( + tcsContext, + sizeof(BYTE *)*revealAttributes.indicesListLength); + if (daaSignature->sA == NULL) { + LogError("malloc of %d bytes failed", + sizeof(BYTE *)*revealAttributes.indicesListLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + length = (DAA_PARAM_SIZE_RANDOMIZED_ATTRIBUTES + 7) / 8; + for( i=0; i<(int)revealAttributes.indicesListLength; i++) { + daaSignature->sA[i] = calloc_tspi( tcsContext, length); + if (daaSignature->sA[i] == NULL) { + LogError("malloc of %d bytes failed", length); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + if( s_A->array[i] == NULL) + bi_2_byte_array( daaSignature->sA[i], length, bi_0); + else { + bi_2_byte_array( daaSignature->sA[i], length, s_A->array[i]); + LogDebug("size big_integer s_A[i] = %ld size daaSignature->sA[i]=%d", + bi_nbin_size( s_A->array[i]), length); + } + } + daaSignature->attributeCommitmentsLength = 0; + daaSignature->signedPseudonym = signature_pseudonym; +close: + bi_free_ptr( tmp1); + if( c_bytes != NULL) free( c_bytes); + if( ch != NULL) free( ch); + if( nonce_tpm != NULL) free( nonce_tpm); + if( encryption_result !=NULL) free( encryption_result); + if( encryption_result_tilde !=NULL) free( encryption_result_tilde); + if( issuer_settings != NULL) free( issuer_settings); + if( r_A != NULL) { + for( i=0; i<(int)revealAttributes.indicesListLength; i++) + if( r_A->array[i] != NULL) bi_free_ptr( r_A->array[i]); + free( r_A); + } + FREE_BI( s_V); + FREE_BI( s_E); + FREE_BI( e); + FREE_BI( sV2); + FREE_BI( sV1); + FREE_BI( sF1); + FREE_BI( sF0); + FREE_BI( c); + FREE_BI( product_R); + FREE_BI( capital_A); + FREE_BI( capital_T_tilde); + FREE_BI( r_V); + FREE_BI( r_E); + FREE_BI( capital_T); + FREE_BI( w); + FREE_BI( capital_N_tilde_v); + FREE_BI( capital_Nv); + FREE_BI( t_tilde_T); + FREE_BI( n); + FREE_BI( capital_gamma); + FREE_BI( gamma); + FREE_BI( zeta); + FREE_BI( r); + free_TSS_DAA_PK_internal( pk_intern); + free_TPM_DAA_ISSUER( tpm_daa_issuer); + return result; +} diff --git a/src/tspi/daa/daa_platform/test.c b/src/tspi/daa/daa_platform/test.c new file mode 100644 index 0000000..04fdd38 --- /dev/null +++ b/src/tspi/daa/daa_platform/test.c @@ -0,0 +1,142 @@ + +#include <stdlib.h> +#include <string.h> +#include <trousers/tss.h> +#include <trousers/trousers.h> +#include "spi_internal_types.h" +#include <spi_utils.h> +#include <obj.h> +#include "tsplog.h" +#include "daa_parameter.h" + +setenv("TCSD_FOREGROUND", "1", 1); + +// simulating Tspi_TPM_DAA_JoinInit (spi_daa.c) +TSS_RESULT Tspi_DAA_Join(TSS_HTPM hTPM, int stage, UINT32 inputSize0, BYTE *inputData0, UINT32 inputSize1, BYTE *inputData1, UINT32 *outputSize, BYTE **outputData) { + TSS_RESULT result; + TCS_CONTEXT_HANDLE tcsContext; + TSS_HCONTEXT tspContext; + TSS_HPOLICY hPolicy; + TCPA_DIGEST digest; + TPM_AUTH ownerAuth; + UINT16 offset = 0; + BYTE hashblob[1000]; + + printf("[%s:%d] obj_tpm_is_connected(hTPM)\n", __FILE__, __LINE__); + if( (result = obj_tpm_is_connected( hTPM, &tcsContext)) != TSS_SUCCESS) return result; + printf("[%s:%d] obj_tpm_get_tsp_context(hTPM)\n", __FILE__, __LINE__); + if( (result = obj_tpm_get_tsp_context( hTPM, &tspContext)) != TSS_SUCCESS) return result; + printf("[%s:%d] obj_tpm_get_policy(hTPM)\n", __FILE__, __LINE__); + if( (result = obj_tpm_get_policy( hTPM, &hPolicy)) != TSS_SUCCESS) return result; + + printf("[%s:%d] Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Join, hashblob)\n", __FILE__, __LINE__); + Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Join, hashblob); // hash TPM_COMMAND_CODE + printf("[%s:%d] Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest)\n",__FILE__, __LINE__); + Trspi_LoadBlob_BYTE(&offset, stage, hashblob); // hash stage + printf("[%s:%d] Trspi_LoadBlob_UINT32(&offset, 0, hashblob)\n",__FILE__, __LINE__); + //TODO old 4 + Trspi_LoadBlob_UINT32(&offset, inputSize0, hashblob); // hash inputSize0 + printf("[%s:%d] Trspi_LoadBlob_UINT32(&offset, 0, hashblob)\n",__FILE__, __LINE__); + Trspi_LoadBlob( &offset, inputSize0, hashblob, inputData0); // hash inputData0 + //TODO old 1 + Trspi_LoadBlob_UINT32(&offset, inputSize1, hashblob); // hash inputSize1 + printf("[%s:%d] Trspi_LoadBlob_UINT32(&offset, 0, hashblob)\n",__FILE__, __LINE__); + Trspi_LoadBlob( &offset, inputSize1, hashblob, inputData1); // hash inputData1 + Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest); + + if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_DAA_Join, + hPolicy, &digest, + &ownerAuth)) != TSS_SUCCESS) return result; + printf("[%s:%d] secret_PerformAuth_OIAP(hTPM, TPM_ORD_DAA_Join ret=%d\n",__FILE__, __LINE__, result); + // out + + /* step of the following call: + TCSP_DAAJoin tcsd_api/calltcsapi.c (define in spi_utils.h) + TCSP_DAAJoin_TP tcsd_api/tcstp.c (define in trctp.h) + */ + + printf("[%s:%d] TCSP_DAAJoin(%x,%x,%x,%x,%x,%x,%x)\n",__FILE__, __LINE__, + (int)hTPM, 0, inputSize0,(int)inputData0,inputSize1,(int)inputData1,(int)&ownerAuth); + if ( (result = TCSP_DaaJoin( tcsContext, hTPM, 0, inputSize0, inputData0, inputSize1, inputData1, &ownerAuth, outputSize, outputData)) != TSS_SUCCESS) + return result; + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, result, hashblob); + Trspi_LoadBlob_UINT32(&offset, TPM_ORD_DAA_Join, hashblob); + Trspi_LoadBlob_UINT32(&offset, *outputSize, hashblob); + Trspi_LoadBlob(&offset, *outputSize, hashblob, *outputData); + Trspi_Hash(TSS_HASH_SHA1, offset, hashblob, digest.digest); + if( (result = obj_policy_validate_auth_oiap( hPolicy, &digest, &ownerAuth))) + { + printf("[%s:%d] obj_policy_validate_auth=%d\n",__FILE__, __LINE__, result); + } + return result; +} + + +int main(int argc, char *argv[]) +{ + TSS_HCONTEXT hContext; + TSS_RESULT result; + TSS_HTPM hTPM; + TSS_HPOLICY hPolicy; + + // Create Context + printf("Create Context\n"); + result = Tspi_Context_Create( &hContext ); + if ( result != TSS_SUCCESS ) + { + fprintf( stderr, "Tspi_Context_Create %d\n", result ); + exit( result ); + } + + // Connect to Context + printf("\nConnect to the context\n"); + result = Tspi_Context_Connect( hContext, NULL ); + if ( result != TSS_SUCCESS ) goto out_close; + + if( (result = Tspi_Context_GetTpmObject( hContext, &hTPM)) != TSS_SUCCESS) + goto out_close; + + // Get the correct policy using the TPM ownership PASSWD + char *szTpmPasswd = "OWN_PWD"; + if( (result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hPolicy)) != TSS_SUCCESS) + goto out_close; + //BUSS + if( (result = Tspi_Policy_SetSecret( hPolicy, TSS_SECRET_MODE_PLAIN, strlen( szTpmPasswd), szTpmPasswd)) != TSS_SUCCESS) + goto out_close; + printf("Tspi_Policy_SetSecret hPolicy received;%d\n", hPolicy); + + //BUSS + // in + //int modulus_length = DAA_PARAM_SIZE_MODULUS_GAMMA / 8; + UINT32 inputSize0 = sizeof(int); + UINT32 inputSize1 = 0; + UINT32 outputSize = 0; + int ia_length = 7; + BYTE *inputData0 = (BYTE *)(&ia_length);//= (BYTE *)malloc( inputSize0) + BYTE *inputData1 = NULL; + BYTE *outputData = NULL; + + if( (result = Tspi_DAA_Join(hTPM, 0, inputSize0, inputData0, inputSize1, inputData1, &outputSize, &outputData)) != TSS_SUCCESS) goto out_close; + + goto out; +out_close: + printf( "Tspi Error:%d - %s\n", result, err_string( result) ); + +out: + printf("ouputSize=%d\n", outputSize); + if( outputData != NULL) { + int i; + printf("outputData(hex )=[\n"); + for( i=0; i<(int)outputSize; i++) printf("%x ", outputData[i]); + printf("\n]"); + printf("outputData(ascii)=[\n"); + for( i=0; i<(int)outputSize; i++) printf("%c ", outputData[i]); + printf("\n]"); + } + Tspi_Context_FreeMemory( hContext, NULL ); + Tspi_Context_Close( hContext ); + printf("[%s:%d] THE END\n",__FILE__, __LINE__); + return result; +} diff --git a/src/tspi/daa/daa_platform/test_join.c b/src/tspi/daa/daa_platform/test_join.c new file mode 100644 index 0000000..a244d85 --- /dev/null +++ b/src/tspi/daa/daa_platform/test_join.c @@ -0,0 +1,504 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include "daa_structs.h" +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "spi_internal_types.h" +#include "spi_utils.h" +#include "obj.h" +#include "tsplog.h" +#include "daa_parameter.h" +#include "verifier.h" +#include "platform.h" + +// for RSA Key +#include <openssl/rsa.h> + +#define DEFAULT_FILENAME "issuer.txt" +#define DEFAULT_CREDENTIAL_FILENAME "credential.txt" +#define DEFAULT_DAACOUNTER 0x01020304 +#define DEFAULT_OWN_PASSWD "OWN_PWD" + +// from IssuerFactory +static const int DEFAULT_KEY_CHAIN_LENGTH = 3; + +typedef struct tdIssuer { + // use on Tspi calls + TSS_DAA_PK *pk_extern; + TSS_DAA_KEY_PAIR *key_pair_extern; + + // used internally + int length_key_chain; + RSA **key_chain; + TSS_DAA_PK_internal *pk; + DAA_PRIVATE_KEY_internal *private_key; + TSS_DAA_PK_PROOF_internal *pk_proof; + //RSA **auth_key_pairs; + BYTE **pk_signatures; + bi_ptr zeta; +} Issuer; + +void *alloc( UINT32 length, TCS_CONTEXT_HANDLE tcsContext) { + void *result = calloc_tspi( tcsContext, length); + LogDebug("allocate tspi memory:%d", (int)result); + return result; +} + +/** +Used by RSA_generate_key +From RSA_generate_key documentation: +-> callback(2, n, cb_arg) is called when n-th randomly generated prime is rejected +-> callback(3, 0, cb_arg) is called when p is found with p-1 more or less prime to e +-> callback(3, 1, cb_arg) repeatedly called for prime q +*/ +void callback(int step, int number, void *arg) { +#ifdef DAA_DEBUG + putc( '.', stdout); fflush( stdout); +#endif +} + +int sign( BYTE *buffer_2_sign, + int len_buffer_2_sign, + RSA *rsa, + BYTE *signature, + int *len_signature +) { + EVP_MD_CTX ctx; + int len_message = EVP_MD_size( EVP_sha1()), current_len_message; + BYTE *message = (BYTE *)malloc( len_message); + int ret; + + EVP_MD_CTX_init(&ctx); + EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL); + EVP_DigestUpdate(&ctx, buffer_2_sign, len_buffer_2_sign); + EVP_DigestFinal_ex(&ctx, message, ¤t_len_message); + LogDebug("Sign rsa-> with message (length=%d)", current_len_message); +// int RSA_sign(int type, unsigned char *m, unsigned int m_len, +// unsigned char *sigret, unsigned int *siglen, RSA *rsa); + ret = RSA_sign( NID_sha1, message, current_len_message, signature, len_signature, rsa); + if( ret == 0) { + LogError("Error in RSA_sign: %s", ERR_error_string( ERR_get_error(), NULL)); + } + LogDebug("Sign rsa-> signature (length=%d)", *len_signature ); + EVP_MD_CTX_cleanup(&ctx); + free( message); + return ret; +} + +/* Compute key chain. */ +static int init_key_chain(int length_key_chain, Issuer *issuer) { + BYTE *signature; + int i, len_sign, ret; + BYTE *modulus; + BYTE *message; + // generate RSA key of length DAA_PARAM_KEY_SIZE with exponent + // 65537 (java.security.spec.RSAKeyGenParameterSpec.F4) + unsigned long e = 65537; + RSA *rsa; + bi_ptr bi; + EVP_MD_CTX ctx; + int len_message = EVP_MD_size( EVP_sha1()); + int current_len_message; + + EVP_MD_CTX_init(&ctx); + message = (BYTE *)malloc(len_message); + if( length_key_chain < 1) { + free( message); + return -1; + } + issuer->length_key_chain = length_key_chain; + issuer->key_chain = (RSA **)malloc(sizeof(RSA *) * length_key_chain); + issuer->pk_signatures = (BYTE **)malloc(sizeof(BYTE *) * length_key_chain); + for(i = 0; i<length_key_chain; i++) { + rsa = RSA_generate_key( DAA_PARAM_KEY_SIZE, e, &callback, NULL); + if( (BN_num_bits(rsa->n) + 7) / 8 != (DAA_PARAM_KEY_SIZE + 7) / 8) { + LogError("BN_num_bits(rsa->n) + 7) / 8 != (DAA_PARAM_KEY_SIZE + 7) / 8)"); + return -1; + } + issuer->key_chain[i] = rsa; + if( i > 0) { + signature = (BYTE *)malloc( RSA_size(rsa)); + modulus = (BYTE *)malloc( DAA_PARAM_KEY_SIZE / 8); + // signature algorithm from Issuer.java - "SHA1withRSA" + // sign the modulus (n) of the RSA key with the previous RSA key (chain) + // sign rsa(i)->n with auth_key_pairs[i-1] + LogDebug("modulus=%s\n", dump_byte_array(256, modulus)); + LogDebug("signature=%s\n", dump_byte_array(256, signature)); + bi = bi_new_ptr(); + bi_set_as_hex( bi, BN_bn2hex( rsa->n)); + bi_2_byte_array( modulus, DAA_PARAM_KEY_SIZE / 8, bi); + LogDebug("bi=%s", bi_2_hex_char( bi)); + bi_free_ptr( bi); + EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL); + EVP_DigestUpdate(&ctx, modulus, DAA_PARAM_KEY_SIZE / 8); + EVP_DigestFinal_ex(&ctx, message, ¤t_len_message); + ret = RSA_sign( NID_sha1, message, current_len_message, + signature, &len_sign, issuer->key_chain[i-1]); + if( ret == 0) { + LogError("Error in RSA_sign: %s", + ERR_error_string( ERR_get_error(), NULL)); + } + LogDebug("Sign rsa->n (length=%d) with signature (length=%d,\ + truelength=%d message_len=%d) ret = %d ERROR?=%s", + RSA_size(rsa), + DAA_PARAM_KEY_SIZE / 8, + len_sign, + current_len_message, + ret, + ERR_error_string( ERR_get_error(), + NULL) ); + LogDebug("message=%s\n", dump_byte_array(256, message)); + LogDebug("signature=%s\n",dump_byte_array(256, signature)); + issuer->pk_signatures[i-1] = signature; + } + } + free( message); + EVP_MD_CTX_cleanup(&ctx); + return 0; +} + +Issuer* initIssuer(int length_key_chain, char *filename, char *exec, TSS_HCONTEXT hContext) { + FILE *file; + EVP_MD_CTX mdctx; + Issuer *issuer = (Issuer *)malloc(sizeof( Issuer)); + TPM_DAA_ISSUER *tpm_daa_issuer; + bi_ptr modulus_N0; + int len_issuer_settings, len_signature; + BYTE *modulus_N0_bytes; + BYTE *digest_n0; + BYTE *issuer_settings_byte_array; + BYTE *sign_data; + BYTE *signature; + RSA *private_nn; + KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof; + + LogDebug("Loading issuer info (keypair & proof) -> \'%s\'", filename); + file = fopen( filename, "r"); + if( file == NULL) { + fprintf( stderr, "%s: Error when opening \'%s\': %s\n", + exec, + filename, + strerror( errno)); + free( issuer); + return NULL; + } + key_pair_with_proof = load_KEY_PAIR_WITH_PROOF( file); + if( key_pair_with_proof == NULL) { + LogError( "Error when reading \'%s\': %s\n", filename, strerror( errno)); + free( issuer); + return NULL; + } + fclose( file); + issuer->pk = key_pair_with_proof->pk; + issuer->pk_extern = i_2_e_TSS_DAA_PK( issuer->pk, &alloc, hContext); + issuer->key_pair_extern = (TSS_DAA_KEY_PAIR *)malloc( sizeof(TSS_DAA_KEY_PAIR)); + init_tss_version( issuer->key_pair_extern); + issuer->key_pair_extern->public_key = issuer->pk_extern; + issuer->key_pair_extern->private_key = i_2_e_TSS_DAA_PRIVATE_KEY( + key_pair_with_proof->private_key, + &alloc, hContext); + issuer->pk_proof = key_pair_with_proof->proof; + issuer->private_key = key_pair_with_proof->private_key; + init_key_chain( length_key_chain, issuer); + issuer->zeta = compute_zeta( issuer->pk->issuerBaseNameLength, + issuer->pk->issuerBaseName, issuer->pk); + // sign "issuer settings" + modulus_N0 = bi_new_ptr(); + bi_set_as_hex( modulus_N0, BN_bn2hex( issuer->key_chain[0]->n)); + // in TPM, N0 is hashed by hashing the scratch (256 bytes) so it must + // be formatted according to the scratch size (TPM_DAA_SIZE_issuerModulus) + modulus_N0_bytes = (BYTE *)malloc( TPM_DAA_SIZE_issuerModulus); + bi_2_byte_array( modulus_N0_bytes, TPM_DAA_SIZE_issuerModulus, modulus_N0); + bi_free_ptr( modulus_N0); + + if( TPM_DAA_SIZE_issuerModulus * 8 != DAA_PARAM_KEY_SIZE) { + LogError("TPM_DAA_SIZE_issuerModulus * 8 (%d) != DAA_PARAM_KEY_SIZE(%d)", + TPM_DAA_SIZE_issuerModulus*8, + DAA_PARAM_KEY_SIZE); + free( issuer); + return NULL; + } + + EVP_MD_CTX_init(&mdctx); + EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL); + // digestN0 = hash( modulus_N0) + EVP_DigestUpdate(&mdctx, modulus_N0_bytes, TPM_DAA_SIZE_issuerModulus); + digest_n0 = (BYTE *)malloc( EVP_MD_CTX_size(&mdctx)); + EVP_DigestFinal_ex(&mdctx, digest_n0, NULL); + tpm_daa_issuer = convert2issuer_settings( issuer->pk); + issuer_settings_byte_array = issuer_2_byte_array( tpm_daa_issuer, &len_issuer_settings); + // data to sign: concatenation of digest_n0 and issuer_settings_byte_array + sign_data = (BYTE *)malloc( EVP_MD_CTX_size(&mdctx) + len_issuer_settings); + memcpy( sign_data, digest_n0, EVP_MD_CTX_size(&mdctx)); + memcpy( &sign_data[EVP_MD_CTX_size(&mdctx)], + issuer_settings_byte_array, + len_issuer_settings); + free( issuer_settings_byte_array); + // sign digest of TPM compatible Issuer key (sign_data) + private_nn = issuer->key_chain[issuer->length_key_chain - 1]; + signature = (BYTE *)malloc( RSA_size(private_nn)); + if ( sign( sign_data, EVP_MD_CTX_size(&mdctx) + len_issuer_settings, + private_nn, + signature, + &len_signature) ==0) { + LogError("Can not sign digest of TPM compatible Issuer key"); + goto close; + } + issuer->pk_signatures[ issuer->length_key_chain - 1] = signature; + LogDebug("Set last signature sign[%d] = %s", + issuer->length_key_chain - 1, + dump_byte_array(EVP_MD_size( EVP_sha1()), + signature)); + // TODO sign the complete public key of TPM compatible Issuer key +/* EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL); + EVP_DigestUpdate(&mdctx, digest_n0, EVP_MD_CTX_size(&mdctx)); + pk_encoded = encoded_DAA_PK_internal( &pk_encodedLength, issuer->pk); + EVP_DigestUpdate(&mdctx, pk_encoded, pk_encodedLength); + EVP_DigestFinal(&mdctx, , NULL); + signature = (BYTE *)malloc( EVP_MD_size( EVP_sha1())); + if (sign( sign_data, EVP_MD_CTX_size(&mdctx) + len_issuer_settings, + private_nn, signature, &len_signature) !=0) goto close; +*/ +close: + free( digest_n0); + free( sign_data); + return issuer; +} + +int print_usage(char *exec) { + fprintf(stderr, "usage: %s\n", exec); + fprintf(stderr, "\t-if,\t--issuer_file\n\t\tthe file that will contain all key\ +pair and proof to be used by the issuer\n\t\t (default: %s)\n", + DEFAULT_FILENAME); + fprintf(stderr, "\t-dc,\t--daa_counter\n\t\tdaa counter (default: %d)\n", + DEFAULT_DAACOUNTER); + fprintf(stderr, + "\t-pw,\t--passwd\n\t\ttpm owner password (default: %s)\n", + DEFAULT_OWN_PASSWD); + return -1; +} + +int main(int argc, char *argv[]) { + TSS_HCONTEXT hContext; + TSS_RESULT result; + TSS_HTPM hTPM; + TSS_HPOLICY hPolicy; + int i, length; + char *param, *filename = DEFAULT_FILENAME; + char *credential_filename = DEFAULT_CREDENTIAL_FILENAME; + UINT32 daaCounter = DEFAULT_DAACOUNTER; + UINT32 capital_UPrimeLength; + BYTE *capitalUPrime; + TSS_DAA_IDENTITY_PROOF identityProof; + TSS_DAA_JOIN_SESSION joinSession; + TSS_DAA_JOIN_ISSUER_SESSION join_issuer_session; + TSS_DAA_CREDENTIAL_REQUEST credentialRequest; + TSS_DAA_CRED_ISSUER credIssuer; + TSS_HDAA hDAA; + Issuer* issuer; + char *szTpmPasswd = DEFAULT_OWN_PASSWD; + UINT32 endorsementKeyLength; + BYTE *endorsementKey; + UINT32 nonceIssuerLength; + BYTE *nonceIssuer; + UINT32 authenticationChallengeLength; + BYTE *authenticationChallenge; + bi_array_ptr capital_receiver; + BYTE **attributesPlatform; + UINT32 attributesPlatformLength; + BYTE **attributesIssuer; + UINT32 attributesIssuerLength; + bi_t random; + FILE *file; + + init_tss_version( &identityProof); + init_tss_version( &joinSession); + init_tss_version( &join_issuer_session); + init_tss_version( &credentialRequest); + init_tss_version( &credIssuer); + i = 1; + while( i < argc) { + param = argv[ i]; + if ( strcmp( param, "-if") == 0 || strcmp( param, "--issuer_file") == 0) { + i++; + if( i == argc) return print_usage( argv[0]); + filename = argv[i]; + } else if( strcmp( param, "-dc") == 0 || strcmp( param, "--daa_counter") == 0){ + i++; + if( i == argc) return print_usage( argv[0]); + daaCounter = atoi(argv[i]); + } else if( strcmp( param, "-pw") == 0 || strcmp( param, "--passwd") == 0){ + i++; + if( i == argc) return print_usage( argv[0]); + szTpmPasswd = argv[i]; + } else { + fprintf(stderr, "\n%s:unrecognized option <%s>\n", argv[0], param); + return print_usage( argv[0]); + } + i++; + } + bi_init( NULL); + + // Create Context + LogDebug("Create Context"); + result = Tspi_Context_Create( &hContext ); + if ( result != TSS_SUCCESS ) + { + LogError( "Tspi_Context_Create %d\n", result ); + goto out; + } + // Connect to Context + result = Tspi_Context_Connect( hContext, NULL ); + if ( result != TSS_SUCCESS) goto out_close; + printf("\nConnect to the context: %X\n", hContext); + + if( (result = Tspi_Context_GetTpmObject( hContext, &hTPM)) != TSS_SUCCESS) + goto out_close; + // Get the correct policy using the TPM ownership PASSWD + if( (result = Tspi_GetPolicyObject( hTPM, + TSS_POLICY_USAGE, + &hPolicy)) != TSS_SUCCESS) + goto out_close; + if( (result = Tspi_Policy_SetSecret( hPolicy, + TSS_SECRET_MODE_PLAIN, + strlen( szTpmPasswd), + szTpmPasswd)) != TSS_SUCCESS) + goto out_close; + LogDebug("Tspi_Policy_SetSecret hPolicy received;%d\n", hPolicy); + + //Create Object + result = obj_daa_add( hContext, &hDAA); + if (result != TSS_SUCCESS) { + LogError("Tspi_Context_CreateObject:%d\n", result); + Tspi_Context_Close(hContext); + LogError("%s: %s\n", argv[0], err_string(result)); + exit(result); + } + LogDebug("created DAA object:%X", hDAA); + issuer = initIssuer( DEFAULT_KEY_CHAIN_LENGTH, filename, argv[0], hContext); + if( issuer == NULL) goto out_close; + + // generate receiver attributes and issuer attributes (random) + attributesPlatformLength = issuer->pk->capitalRReceiver->length; + attributesPlatform = (BYTE **)malloc( attributesPlatformLength * sizeof(BYTE *)); + bi_new( random); + for( i=0; i<(int)attributesPlatformLength; i++) { + bi_urandom( random, DAA_PARAM_SIZE_F_I); + attributesPlatform[i] = bi_2_nbin( &length, random); + if( attributesPlatform[i] == NULL) { + LogError("malloc of %d bytes failed", length); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto out_close; + } + } + attributesIssuerLength = issuer->pk->capitalRIssuer->length; + attributesIssuer = (BYTE **)malloc( attributesIssuerLength * sizeof(BYTE *)); + for( i=0; i<(int)attributesIssuerLength; i++) { + bi_urandom( random, DAA_PARAM_SIZE_F_I); + attributesIssuer[i] = bi_2_nbin( &length, random); + if( attributesIssuer[i] == NULL) { + LogError("malloc of %d bytes failed", length); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto out_close; + } + } + bi_free(random); + LogDebug("Generated attributes (Platform=%d,Issuer=%d)", + attributesPlatformLength, attributesIssuerLength); + + result = Tspi_TPM_DAA_JoinInit( + hDAA, // in + hTPM, // in + daaCounter, // in + (TSS_HKEY)issuer->pk_extern, // in + issuer->length_key_chain, // in + (TSS_HKEY *)issuer->key_chain, // in + issuer->length_key_chain, // in + issuer->pk_signatures, // in + &capital_UPrimeLength, // out + &capitalUPrime, // out + &identityProof, // out + &joinSession // out + ); + if( result != TSS_SUCCESS) goto out_close; + + result = Tspi_DAA_IssueInit( + hDAA, // in + (TSS_HKEY)issuer->key_chain[0], // in + (TSS_HKEY)issuer->key_pair_extern, // in + identityProof, // in + capital_UPrimeLength, // in + capitalUPrime, // in + daaCounter, // in + &nonceIssuerLength, // out + &nonceIssuer, // out + &authenticationChallengeLength, // out + &authenticationChallenge, // out + &join_issuer_session // out + ); + if( result != TSS_SUCCESS) goto out_close; + + result = Tspi_TPM_DAA_JoinCreateDaaPubKey( + hDAA, // in + hTPM, // in + authenticationChallengeLength, // in + authenticationChallenge, // in + nonceIssuerLength, // in + nonceIssuer, // in + attributesPlatformLength, // in + attributesPlatform, // in + &joinSession, // in & out + &credentialRequest // out + ); + if( result != TSS_SUCCESS) goto out_close; + + result = Tspi_DAA_IssueCredential( + hDAA, // in + attributesIssuerLength, // in + attributesIssuer, // in + credentialRequest, // in + join_issuer_session, // in + &credIssuer // out + ); + + result = Tspi_TPM_DAA_JoinStoreCredential( + hDAA, // in + hTPM, // in + credIssuer, // in + joinSession, // in + (TSS_HKEY*)&credentialRequest // out + ); + if( result != TSS_SUCCESS) goto out_close; + + printf("Saving credential: %s ", credential_filename); + file = fopen( credential_filename, "w"); + if( save_TSS_DAA_CREDENTIAL( file, &credentialRequest) != 0) { + LogError( "[test_join]: Error when saving \'%s\': %s", + credential_filename, + strerror( errno)); + result = TSS_E_FAIL; + goto out_close; + } + fclose( file); + printf("Done\n"); + +out_close: + Tspi_Context_FreeMemory( hContext, NULL ); + Tspi_Context_Close( hContext ); +out: + bi_release(); + LogDebug("THE END result=%d:%s",result, err_string( result) );; + return result; +} diff --git a/src/tspi/daa/daa_structs.c b/src/tspi/daa/daa_structs.c new file mode 100644 index 0000000..787d5d0 --- /dev/null +++ b/src/tspi/daa/daa_structs.c @@ -0,0 +1,1317 @@ + +/* +* Licensed Materials - Property of IBM +* +* trousers - An open source TCG Software Stack +* +* (C) Copyright International Business Machines Corp. 2006 +* +*/ + +/* +This file implements Helper functions for converting / creating and freeing +internal representation of TSS_DAA structures. +An external representation is the one define in tss_structs.h. +An internal representation is using bi_t or bi_ptr for representing big numbers. +Naming convention: for each structures we can have: +init_(<STRUCT>, struct *) : initialize the version field +create_<STRUCT> : init all fields +free_<STRUCT> : free all fields +e_2_i_<STRUCT> : convertor from External representation to internal +i_2_e_<STRUCT> : convertor from Internal to External. This call use a given memory +allocation function, to allow +for example to use calloc_tspi, or a "normal" malloc. +*/ +#include <stdio.h> +#include <strings.h> +#include <errno.h> +#include <strings.h> + +#include "daa_parameter.h" +#include "daa_structs.h" +#include "tcslog.h" + +#define DUMP_DAA_PK_FIELD( field) \ +do { \ + printf("%s=", #field); \ + dump_field( pk->field##Length, pk->field); \ + puts(""); \ +} while(0); + +#if 0 +#define STORE_DAA_PK_BI1( field, bi) \ +do { \ + store_bi( &pk->field##Length, &pk->field, bi); \ +} while(0); + +#define STORE_DAA_PK_BI( field, daa_alloc, param_alloc) \ +do { \ + store_bi( &pk->field##Length,\ + &pk->field,\ + pk_internal->field,\ + daa_alloc,\ + param_alloc); \ +} while(0); + +// used only to read a structure from a file, so only as helping function +// for TCG application +static char buffer[1000]; +#endif +BYTE *convert_alloc( TCS_CONTEXT_HANDLE tcsContext, UINT32 length, BYTE *source) { + BYTE *result = calloc_tspi( tcsContext, length); + + if( result == NULL) return NULL; + memcpy( result, source, length); + free( source); + return result; +} + +BYTE *copy_alloc( TCS_CONTEXT_HANDLE tcsContext, UINT32 length, BYTE *source) { + BYTE *result = calloc_tspi( tcsContext, length); + + if( result == NULL) return NULL; + memcpy( result, source, length); + return result; +} + +static void *normal_malloc( size_t size, TSS_HOBJECT object) { + void *ret = malloc( size); + return ret; +} + +/* store a bi to a buffer and update the length in big endian format */ +void store_bi( UINT32 *length, + BYTE **buffer, + const bi_ptr i, + void * (*daa_alloc)(size_t size, TSS_HOBJECT object), + TSS_HOBJECT object +) { + int size; + + *buffer = (BYTE *)daa_alloc( bi_length( i), object); + bi_2_nbin1( &size, *buffer, i); + *length = size; + LogDebug( "[store_bi] host_length:%d network_length:%d[address:%d]\n", + size, + (int)*length, + (int)*buffer); +} + +bi_ptr get_bi( const unsigned long n_length, const BYTE *buffer) { + unsigned long length; + + length = n_length; + LogDebug( "[get_bi] %d [address:%d -> |%2x|%2x| ]\n", + (int)length, + (int)buffer, + (int)(buffer[0] &0xFF), + (int)(buffer[1]&0xFF)); + return bi_set_as_nbin( length, buffer); +} + +/* length is in network format: big indian */ +void dump_field( int length, BYTE *buffer) { + int i; + + for( i=0; i< length; i++) { + BYTE byte = (BYTE)(buffer[i] & 0xFF); + printf("%02X", byte); + } +} + +#if 0 +/* !: do not keep the return buffer */ +char *read_str(FILE *file) { + int i; + char c; + + fgets( buffer, 1000, file); + i=0; + while( buffer[i] =='\n' || buffer[i]=='\r' || buffer[i]==' ') i++; + do { + c = buffer[ i++]; + } while( c != 0 && c != ' ' && c!='\n' && c!='\r' && c!='#'); + buffer[ i -1] = 0; + return buffer; +} + +/** + * + * @param file + * @return + */ +int read_int( FILE *file) { + int i, ret; + char c; + + fgets( buffer, 1000, file); + i=0; + while( buffer[i] =='\n' || buffer[i]=='\r' || buffer[i]==' ') i++; + do { + c = buffer[ i++]; + } while( c != 0 && c != ' ' && c!='\n' && c!='\r' && c!='#'); + buffer[ i -1] = 0; + sscanf( buffer, "%d", &ret); + return ret; +} +#endif +/******************************************************************************************** +* TSS_DAA_SELECTED_ATTRIB +* this struct is used internally and externally, only a call to +internal_2_DAA_SELECTED_ATTRIB +* and DAA_SELECTED_ATTRIB_2_internal will change the struct to be internal or +external +********************************************************************************************/ + +void i_2_e_TSS_DAA_SELECTED_ATTRIB( + TSS_DAA_SELECTED_ATTRIB *selected_attrib +) { +} + +void e_2_i_TSS_DAA_SELECTED_ATTRIB( + TSS_DAA_SELECTED_ATTRIB *selected_attrib +) { +} + +/* work ONLY with internal format +important: TSS_BOOL is of type int_8_t, so a char, if the size is bigger, we +will maybe need +to transform each part to big indian ? or maybe each part is false if equal to +0, true otherwise. +*/ +BYTE *to_bytes_TSS_DAA_SELECTED_ATTRIB_internal( + int *result_length, + TSS_DAA_SELECTED_ATTRIB *selected_attrib +) { + BYTE *result; + int index = 0; + unsigned int length = selected_attrib->indicesListLength; + + *result_length = sizeof(unsigned int) + + (selected_attrib->indicesListLength * sizeof(TSS_BOOL)); + result = (BYTE *)malloc( *result_length); + memcpy( &result[index], &length, sizeof(UINT32)); + index+=sizeof(UINT32); + memcpy( &result[index], selected_attrib->indicesList, + sizeof(TSS_BOOL) * selected_attrib->indicesListLength); + return result; +} + +/* +create a TSS_DAA_SELECTED_ATTRIB of length <length> with given selected attributes. +example of selections of the second and third attributes upon 5: +create_TSS_DAA_SELECTED_ATTRIB( &selected_attrib, 5, 0, 1, 1, 0, 0); +*/ +void create_TSS_DAA_SELECTED_ATTRIB( TSS_DAA_SELECTED_ATTRIB *attrib, int length, ...) { + va_list ap; + int i, select; + + attrib->indicesListLength = length; + attrib->indicesList = (TSS_BOOL *)malloc( length * sizeof( TSS_BOOL)); + va_start (ap, length); + for( i=0; i<length; i++) { + select = va_arg( ap, int) != 0; + attrib->indicesList[i] = select; + } + va_end (ap); +} + + +/****************************************************************************************** +* TSS_DAA_SIGN_DATA +* this struct is used internally and externally, only a call to internal_2_DAA_SIGN_DATA +* DAA_SIGN_DATA_2_internal will change the struct to be internal or external +*******************************************************************************************/ + +void i_2_e_TSS_DAA_SIGN_DATA( TSS_DAA_SIGN_DATA *sign_data) { +} + +void e_2_i_TSS_DAA_SIGN( TSS_DAA_SIGN_DATA *sign_data) { +} + +/******************************************************************************************** +* TSS_DAA_ATTRIB_COMMIT +********************************************************************************************/ + +TSS_DAA_ATTRIB_COMMIT_internal *create_TSS_DAA_ATTRIB_COMMIT( bi_ptr beta, bi_ptr sMu) { + TSS_DAA_ATTRIB_COMMIT_internal *result = + (TSS_DAA_ATTRIB_COMMIT_internal *)malloc( sizeof(TSS_DAA_ATTRIB_COMMIT_internal)); + + result->beta = beta; + result->sMu = sMu; + return result; +} + + +/******************************************************************************************** +* TSS_DAA_PSEUDONYM_PLAIN +********************************************************************************************/ + +TSS_DAA_PSEUDONYM_PLAIN_internal * +create_TSS_DAA_PSEUDONYM_PLAIN(bi_ptr nV) +{ + TSS_DAA_PSEUDONYM_PLAIN_internal *result = (TSS_DAA_PSEUDONYM_PLAIN_internal *) + malloc(sizeof(TSS_DAA_PSEUDONYM_PLAIN_internal)); + + result->nV = nV; + return result; +} + +/******************************************************************************************** +* DAA PRIVATE KEY +********************************************************************************************/ +/* +* allocate: ret->p_prime +* ret->q_prime +* ret->productPQprime +*/ +DAA_PRIVATE_KEY_internal * +create_TSS_DAA_PRIVATE_KEY(bi_ptr pPrime, bi_ptr qPrime) +{ + DAA_PRIVATE_KEY_internal *private_key = + (DAA_PRIVATE_KEY_internal *)malloc( sizeof( DAA_PRIVATE_KEY_internal)); + + private_key->p_prime = bi_new_ptr(); bi_set( private_key->p_prime, pPrime); + private_key->q_prime = bi_new_ptr(); bi_set( private_key->q_prime, qPrime); + private_key->productPQprime = bi_new_ptr(); + bi_mul( private_key->productPQprime, pPrime, qPrime); + return private_key; +} + +#if 0 +int +save_DAA_PRIVATE_KEY(FILE *file, const DAA_PRIVATE_KEY_internal *private_key) +{ + BI_SAVE( private_key->p_prime , file); + BI_SAVE( private_key->q_prime , file); + BI_SAVE( private_key->productPQprime, file); + return 0; +} + +DAA_PRIVATE_KEY_internal * +load_DAA_PRIVATE_KEY(FILE *file) +{ + DAA_PRIVATE_KEY_internal *private_key = + (DAA_PRIVATE_KEY_internal *)malloc( sizeof(DAA_PRIVATE_KEY_internal)); + + private_key->p_prime = bi_new_ptr(); + BI_LOAD( private_key->p_prime, file); + private_key->q_prime = bi_new_ptr(); + BI_LOAD( private_key->q_prime, file); + private_key->productPQprime = bi_new_ptr(); + BI_LOAD( private_key->productPQprime, file); + return private_key; +} +#endif +DAA_PRIVATE_KEY_internal *e_2_i_TSS_DAA_PRIVATE_KEY(TSS_DAA_PRIVATE_KEY *private_key) { + DAA_PRIVATE_KEY_internal *private_key_internal; + + LogDebug("-> e_2_i_TSS_DAA_PRIVATE_KEY"); + private_key_internal = + (DAA_PRIVATE_KEY_internal *)malloc( sizeof(DAA_PRIVATE_KEY_internal)); + private_key_internal->p_prime = get_bi( private_key->p_primeLength, private_key->p_prime); + private_key_internal->q_prime = get_bi( private_key->q_primeLength, private_key->q_prime); + private_key_internal->productPQprime = + get_bi( private_key->productPQprimeLength, private_key->productPQprime); + LogDebug("<- e_2_i_TSS_DAA_PRIVATE_KEY"); + return private_key_internal; +} + +TSS_DAA_PRIVATE_KEY * +i_2_e_TSS_DAA_PRIVATE_KEY(DAA_PRIVATE_KEY_internal *private_key_internal, + void * (*daa_alloc)(size_t size, TSS_HOBJECT object), + TSS_HOBJECT param_alloc) +{ + TSS_DAA_PRIVATE_KEY *result; + + LogDebug("-> i_2_e_TSS_DAA_PRIVATE_KEY"); + result = (TSS_DAA_PRIVATE_KEY *)daa_alloc( sizeof(TSS_DAA_PRIVATE_KEY), param_alloc); + init_tss_version( result); + store_bi( &(result->p_primeLength), + &(result->p_prime), + private_key_internal->p_prime, + daa_alloc, + param_alloc); + store_bi( &(result->q_primeLength), + &(result->q_prime), + private_key_internal->q_prime, + daa_alloc, + param_alloc); + store_bi( &(result->productPQprimeLength), + &(result->productPQprime), + private_key_internal->productPQprime, + daa_alloc, + param_alloc); + LogDebug("<- i_2_e_TSS_DAA_PRIVATE_KEY"); + return result; +} + +/******************************************************************************************** +* KEY PAIR WITH PROOF +********************************************************************************************/ + +#if 0 + +/* moved to daa_debug.c */ + +int +save_KEY_PAIR_WITH_PROOF(FILE *file, + KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof) +{ + save_DAA_PK_internal( file, key_pair_with_proof->pk); + save_DAA_PRIVATE_KEY( file, key_pair_with_proof->private_key); + save_DAA_PK_PROOF_internal( file, key_pair_with_proof->proof); + + return 0; +} + +KEY_PAIR_WITH_PROOF_internal * +load_KEY_PAIR_WITH_PROOF(FILE *file) +{ + KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof = + (KEY_PAIR_WITH_PROOF_internal *)malloc(sizeof(KEY_PAIR_WITH_PROOF_internal)); + + key_pair_with_proof->pk = load_DAA_PK_internal(file); + key_pair_with_proof->private_key = load_DAA_PRIVATE_KEY(file); + key_pair_with_proof->proof = load_DAA_PK_PROOF_internal(file); + + return key_pair_with_proof; +} + +#endif +/* allocated using instrumented daa_alloc */ +TSS_DAA_KEY_PAIR *get_TSS_DAA_KEY_PAIR(KEY_PAIR_WITH_PROOF_internal *key_pair_with_proof, + void * (*daa_alloc)(size_t size, TSS_HOBJECT object), + TSS_HOBJECT param_alloc) +{ + TSS_DAA_KEY_PAIR *result; + + LogDebug("-> i_2_e_KEY_PAIR_WITH_PROOF"); + + result = (TSS_DAA_KEY_PAIR *)daa_alloc(sizeof(TSS_DAA_KEY_PAIR), param_alloc); + init_tss_version(result); + result->private_key = i_2_e_TSS_DAA_PRIVATE_KEY(key_pair_with_proof->private_key, + daa_alloc, param_alloc); + result->public_key = i_2_e_TSS_DAA_PK( key_pair_with_proof->pk, daa_alloc, param_alloc); + + LogDebug("<- i_2_e_KEY_PAIR_WITH_PROOF"); + + return result; +} + + +/******************************************************************************************** +* TSS_DAA_PK +********************************************************************************************/ + +/* pk_internal->capitalY must be alocated using ALLOC_BI_ARRAY() */ +void +populate_capitalY(TSS_DAA_PK_internal *pk_internal) +{ + int i; + + bi_new_array(pk_internal->capitalY, + pk_internal->capitalRReceiver->length + pk_internal->capitalRIssuer->length); + + // CAPITAL Y ( capitalRReceiver ) + for (i = 0; i < pk_internal->capitalRReceiver->length; i++) + pk_internal->capitalY->array[i] = pk_internal->capitalRReceiver->array[i]; + // CAPITAL Y ( capitalRIssuer) + for (i = 0; i < pk_internal->capitalRIssuer->length; i++) + pk_internal->capitalY->array[pk_internal->capitalRReceiver->length+i] = + pk_internal->capitalRIssuer->array[i]; +} + +void +compute_capitalSprime(TSS_DAA_PK_internal *pk_internal) +{ + bi_t bi_tmp; + + bi_new(bi_tmp); + pk_internal->capitalSprime = bi_new_ptr(); + bi_shift_left( bi_tmp, bi_1, DAA_PARAM_SIZE_SPLIT_EXPONENT); + bi_mod_exp(pk_internal->capitalSprime, pk_internal->capitalS, bi_tmp, pk_internal->modulus); + bi_free( bi_tmp); +} + +/* +* create anf feel a TSS_DAA_PK_internal structures +* ! this function keep pointer on all parameters +*/ +TSS_DAA_PK_internal * +create_DAA_PK(const bi_ptr modulus, + const bi_ptr capitalS, + const bi_ptr capitalZ, + const bi_ptr capitalR0, + const bi_ptr capitalR1, + const bi_ptr gamma, + const bi_ptr capitalGamma, + const bi_ptr rho, + const bi_array_ptr capitalRReceiver, + const bi_array_ptr capitalRIssuer, + const int issuerBaseNameLength, + BYTE * const issuerBaseName) +{ + TSS_DAA_PK_internal *pk_internal; + + LogDebug("-> create_DAA_PK"); + pk_internal = (TSS_DAA_PK_internal *)malloc(sizeof(TSS_DAA_PK_internal)); + pk_internal->modulus = modulus; + pk_internal->capitalS = capitalS; + pk_internal->capitalZ = capitalZ; + pk_internal->capitalR0 = capitalR0; + pk_internal->capitalR1 = capitalR1; + pk_internal->gamma = gamma; + pk_internal->capitalGamma = capitalGamma; + pk_internal->rho = rho; + pk_internal->capitalRReceiver = capitalRReceiver; + pk_internal->capitalRIssuer = capitalRIssuer; + pk_internal->capitalY = ALLOC_BI_ARRAY(); + populate_capitalY( pk_internal); + pk_internal->issuerBaseNameLength = issuerBaseNameLength; + pk_internal->issuerBaseName = issuerBaseName; + compute_capitalSprime( pk_internal); + + LogDebug("<- create_DAA_PK"); + + return pk_internal; +} + +#if 0 + +/* moved to daa_debug.c */ + +int +save_DAA_PK_internal(FILE *file, const TSS_DAA_PK_internal *pk_internal) +{ + char *buffer; + + LogDebug("-> save_DAA_PK_internal"); + + BI_SAVE( pk_internal->modulus, file); + BI_SAVE( pk_internal->capitalS, file); + BI_SAVE( pk_internal->capitalZ, file); + BI_SAVE( pk_internal->capitalR0, file); + BI_SAVE( pk_internal->capitalR1, file); + BI_SAVE( pk_internal->gamma, file); + BI_SAVE( pk_internal->capitalGamma, file); + BI_SAVE( pk_internal->rho, file); + BI_SAVE_ARRAY( pk_internal->capitalRReceiver, file); + BI_SAVE_ARRAY( pk_internal->capitalRIssuer, file); + fprintf( file, "%d\n", pk_internal->issuerBaseNameLength); + buffer = (char *)malloc( pk_internal->issuerBaseNameLength + 1); + memcpy( buffer, pk_internal->issuerBaseName, pk_internal->issuerBaseNameLength); + buffer[ pk_internal->issuerBaseNameLength] = 0; + fprintf( file, "%s\n", buffer); + free( buffer); + + LogDebug("<- save_DAA_PK_internal"); + + return 0; +} + +TSS_DAA_PK_internal * +load_DAA_PK_internal(FILE *file) +{ + TSS_DAA_PK_internal *pk_internal = + (TSS_DAA_PK_internal *)malloc(sizeof(TSS_DAA_PK_internal)); + char *read_buffer; + + pk_internal->modulus = bi_new_ptr(); + BI_LOAD( pk_internal->modulus, file); + pk_internal->capitalS = bi_new_ptr(); + BI_LOAD( pk_internal->capitalS, file); + pk_internal->capitalZ = bi_new_ptr(); + BI_LOAD( pk_internal->capitalZ, file); + pk_internal->capitalR0 = bi_new_ptr(); + BI_LOAD( pk_internal->capitalR0, file); + pk_internal->capitalR1 = bi_new_ptr(); + BI_LOAD( pk_internal->capitalR1, file); + pk_internal->gamma = bi_new_ptr(); + BI_LOAD( pk_internal->gamma, file); + pk_internal->capitalGamma = bi_new_ptr(); + BI_LOAD( pk_internal->capitalGamma, file); + pk_internal->rho = bi_new_ptr(); + BI_LOAD( pk_internal->rho, file); + pk_internal->capitalRReceiver = ALLOC_BI_ARRAY(); + BI_LOAD_ARRAY( pk_internal->capitalRReceiver, file); + pk_internal->capitalRIssuer = ALLOC_BI_ARRAY(); + BI_LOAD_ARRAY( pk_internal->capitalRIssuer, file); + pk_internal->capitalY = ALLOC_BI_ARRAY(); + populate_capitalY( pk_internal); + pk_internal->issuerBaseNameLength = read_int( file); + read_buffer = read_str( file); + pk_internal->issuerBaseName = malloc( pk_internal->issuerBaseNameLength); + memcpy( pk_internal->issuerBaseName, read_buffer, pk_internal->issuerBaseNameLength); + compute_capitalSprime( pk_internal); + return pk_internal; +} + +#endif +void +dump_DAA_PK_internal(char *name, TSS_DAA_PK_internal *pk_internal) +{ + LogDebug("Dump TSS_DAA_PK_internal:%s\n", name); + + DUMP_BI( pk_internal->modulus); + DUMP_BI( pk_internal->capitalS); + DUMP_BI( pk_internal->capitalZ); + DUMP_BI( pk_internal->capitalR0); + DUMP_BI( pk_internal->capitalR1); + DUMP_BI( pk_internal->gamma); + DUMP_BI( pk_internal->capitalGamma); + DUMP_BI( pk_internal->rho); + DUMP_BI_ARRAY( pk_internal->capitalRReceiver); + DUMP_BI_ARRAY( pk_internal->capitalRIssuer); + + LogDebug("issuerBaseName = %s\n", pk_internal->issuerBaseName); + LogDebug("End Dump TSS_DAA_PK_internal:%s\n", name); +} + +/* +* Encode the DAA_PK like java.security.Key#getEncoded +*/ +BYTE * +encoded_DAA_PK_internal(int *result_length, const TSS_DAA_PK_internal *pk) +{ + int length_issuer_base_name = pk->issuerBaseNameLength; + int total_length = DAA_PARAM_TSS_VERSION_LENGTH + + 5 * ((DAA_PARAM_SIZE_RSA_MODULUS / 8)+ sizeof(int)) + + 2 * ((DAA_PARAM_SIZE_MODULUS_GAMMA / 8)+sizeof(int)) + + 1 * ((DAA_PARAM_SIZE_RHO / 8)+sizeof(int)) + + pk->capitalY->length*(((DAA_PARAM_SIZE_RSA_MODULUS / 8)+sizeof(int))) + + length_issuer_base_name; + BYTE *result = (BYTE *)malloc(total_length); + int i, index = 0, length, big_indian_length; + + if (result == NULL) + return NULL; + + LogDebug("total_length=%d", total_length); + for (index = 0; index < DAA_PARAM_TSS_VERSION_LENGTH; index++) + result[index] = DAA_PARAM_TSS_VERSION[index]; + // n, capitalS, capitalZ, capitalR0, capitalR1 + length = DAA_PARAM_SIZE_RSA_MODULUS / 8; + big_indian_length = length; + memcpy(&result[index], &big_indian_length, sizeof(int)); + index += sizeof(int); + bi_2_byte_array( &result[index], length, pk->modulus); + index += length; + memcpy(&result[index], &big_indian_length, sizeof(int)); + index += sizeof(int); + bi_2_byte_array( &result[index], length, pk->capitalS); + index += length; + memcpy(&result[index], &big_indian_length, sizeof(int)); + index += sizeof(int); + bi_2_byte_array( &result[index], length, pk->capitalZ); + index += length; + memcpy(&result[index], &big_indian_length, sizeof(int)); + index += sizeof(int); + bi_2_byte_array( &result[index], length, pk->capitalR0); + index += length; + memcpy(&result[index], &big_indian_length, sizeof(int)); + index += sizeof(int); + bi_2_byte_array( &result[index], length, pk->capitalR1); + index += length; + // gamma, capitalGamma + length = DAA_PARAM_SIZE_MODULUS_GAMMA / 8; + big_indian_length = length; + memcpy(&result[index], &big_indian_length, sizeof(int)); + index += sizeof(int); + bi_2_byte_array( &result[index], length, pk->gamma); + index += length; + memcpy(&result[index], &big_indian_length, sizeof(int)); + index += sizeof(int); + bi_2_byte_array( &result[index], length, pk->capitalGamma); + index += length; + // rho + length = DAA_PARAM_SIZE_RHO / 8; + big_indian_length = length; + memcpy(&result[index], &big_indian_length, sizeof(int)); + index += sizeof(int); + bi_2_byte_array( &result[index], length, pk->rho); + index += length; + // capitalY + length = DAA_PARAM_SIZE_RSA_MODULUS / 8; + big_indian_length = length; + + for( i=0; i<pk->capitalY->length; i++) { + memcpy( &result[index], &big_indian_length, sizeof(int)); + index+=sizeof(int); + bi_2_byte_array( &result[index], length, pk->capitalY->array[i]); + index+=length; + } + // basename + memcpy( &result[index], pk->issuerBaseName, length_issuer_base_name); + index+=length_issuer_base_name; + *result_length = index; + + LogDebug("return length=%d", index); + + return result; +} + +/* create anf feel a TSS_DAA_PK structures */ +TSS_DAA_PK * +i_2_e_TSS_DAA_PK(TSS_DAA_PK_internal *pk_internal, + void *(*daa_alloc)(size_t size, TSS_HOBJECT param_alloc), + TSS_HOBJECT param_alloc) +{ + int i; + int capitalYLength; + int capitalYLength2; + TSS_DAA_PK *pk; + + LogDebug("-> i_2_e_TSS_DAA_PK"); + pk = (TSS_DAA_PK *)daa_alloc( sizeof(TSS_DAA_PK), param_alloc); + init_tss_version( pk); + if (pk == NULL) { + LogError("Can not allocate the TSS_DAA_PK structure"); + return NULL; + } + STORE_DAA_PK_BI( modulus, daa_alloc, param_alloc); + STORE_DAA_PK_BI( capitalS, daa_alloc, param_alloc); + STORE_DAA_PK_BI( capitalZ, daa_alloc, param_alloc); + STORE_DAA_PK_BI( capitalR0, daa_alloc, param_alloc); + STORE_DAA_PK_BI( capitalR1, daa_alloc, param_alloc); + STORE_DAA_PK_BI( gamma, daa_alloc, param_alloc); + STORE_DAA_PK_BI( capitalGamma, daa_alloc, param_alloc); + STORE_DAA_PK_BI( rho, daa_alloc, param_alloc); + capitalYLength = pk_internal->capitalY->length; + capitalYLength2 = bi_nbin_size( pk_internal->capitalY->array[0]); + LogDebug("[capitalYLength=%d capitalYLength2=%d total size=%d]\n", + capitalYLength, capitalYLength2, sizeof(BYTE) * capitalYLength * + capitalYLength2); + pk->capitalY = (BYTE **) daa_alloc( sizeof(BYTE *) * capitalYLength, param_alloc ); + for (i = 0; i < capitalYLength; i++) { + if( bi_nbin_size( pk_internal->capitalY->array[i]) != capitalYLength2) { + // LOG ERROR + LogError("Error during feel operation of capitalY (index=%d capitalYLength" + "2=%d, currentSize=%d)\n", i, capitalYLength2, + (int)bi_nbin_size(pk_internal->capitalY->array[i])); + } + BYTE *buffer = (BYTE*) daa_alloc( sizeof(BYTE) * capitalYLength2, param_alloc); + bi_2_byte_array( buffer, capitalYLength2, pk_internal->capitalY->array[i]); + // bi_2_nbin1( &checkSize, buffer, pk_internal->capitalY->array[i]); + pk->capitalY[i] = buffer; + LogDebug( "[i=%d currentsize=%d buffer[%d]=[%2x|%2x]\n", + i, + (int)bi_nbin_size( pk_internal->capitalY->array[i]), + (int)pk->capitalY[i], + (int)pk->capitalY[i][0], + (int)pk->capitalY[i][1]); + } + pk->capitalYLength = capitalYLength; + pk->capitalYLength2 = capitalYLength2; + pk->capitalYPlatformLength = pk_internal->capitalRReceiver->length; + LogDebug("issuer= len=%d", pk_internal->issuerBaseNameLength); + pk->issuerBaseNameLength = pk_internal->issuerBaseNameLength; + pk->issuerBaseName = (BYTE *)daa_alloc(pk_internal->issuerBaseNameLength, param_alloc); + memcpy( pk->issuerBaseName, + pk_internal->issuerBaseName, + pk_internal->issuerBaseNameLength); + LogDebug("i_2_e_TSS_DAA_PK extern_issuer=%s intern_issuer=%s\n", + pk->issuerBaseName, + pk_internal->issuerBaseName); + LogDebug("<- i_2_e_TSS_DAA_PK"); + return pk; +} + +/**/ +TSS_DAA_PK_internal * +e_2_i_TSS_DAA_PK( TSS_DAA_PK *pk) +{ + TSS_DAA_PK_internal *pk_internal = + (TSS_DAA_PK_internal *)malloc(sizeof(TSS_DAA_PK_internal)); + unsigned long capitalYLength, capitalYLength2, capitalYPlatformLength; + UINT32 i; + int issuer_length; + + // pk_internal->modulus = GET_DAA_PK_BI( modulus); + pk_internal->modulus = get_bi(pk->modulusLength, pk->modulus); + pk_internal->capitalS = get_bi(pk->capitalSLength, pk->capitalS); + pk_internal->capitalZ = get_bi(pk->capitalZLength, pk->capitalZ); + pk_internal->capitalR0 = get_bi(pk->capitalR0Length, pk->capitalR0); + pk_internal->capitalR1 = get_bi(pk->capitalR1Length, pk->capitalR1); + pk_internal->gamma = get_bi(pk->gammaLength, pk->gamma); + pk_internal->capitalGamma = get_bi(pk->capitalGammaLength, pk->capitalGamma); + pk_internal->rho = get_bi(pk->rhoLength, pk->rho); + capitalYLength = pk->capitalYLength; + capitalYLength2= pk->capitalYLength2; + capitalYPlatformLength = pk->capitalYPlatformLength; + LogDebug( "capitalYLength:%ld capitalYLength2:%ld capitalYPlatformLength:%ld\n", + capitalYLength, capitalYLength2, capitalYPlatformLength); + + pk_internal->capitalRReceiver = ALLOC_BI_ARRAY(); + bi_new_array2(pk_internal->capitalRReceiver, capitalYPlatformLength); + for (i = 0; i < capitalYPlatformLength; i++) { + LogDebug( "i=%d\n", i); + pk_internal->capitalRReceiver->array[i] = + get_bi(pk->capitalYLength2, pk->capitalY[i]); + } + pk_internal->capitalRIssuer = ALLOC_BI_ARRAY(); + bi_new_array2( pk_internal->capitalRIssuer, capitalYLength - + capitalYPlatformLength); + for( ; i<capitalYLength; i++) { + pk_internal->capitalRIssuer->array[ i - capitalYPlatformLength] = + get_bi( pk->capitalYLength2, pk->capitalY[i]); + } + pk_internal->capitalY = ALLOC_BI_ARRAY(); + populate_capitalY( pk_internal); + issuer_length = pk->issuerBaseNameLength; + pk_internal->issuerBaseNameLength = issuer_length; + LogDebug( "issuer_length=%d\n", issuer_length); + pk_internal->issuerBaseName = (BYTE *)malloc( issuer_length); + memcpy( pk_internal->issuerBaseName, pk->issuerBaseName, issuer_length); + LogDebug("e_2_i_TSS_DAA_PK extern_issuer=%s intern_issuer=%s\n", + pk->issuerBaseName, + pk_internal->issuerBaseName); + compute_capitalSprime( pk_internal); // allocation + return pk_internal; +} + +void +free_TSS_DAA_PK_internal(TSS_DAA_PK_internal *pk_internal) +{ + bi_free_ptr( pk_internal->capitalSprime); + free( pk_internal->issuerBaseName); + free( pk_internal->capitalY); + bi_free_array( pk_internal->capitalRIssuer); + bi_free_array( pk_internal->capitalRReceiver); + bi_free_ptr( pk_internal->rho); + bi_free_ptr( pk_internal->capitalGamma); + bi_free_ptr( pk_internal->gamma); + bi_free_ptr( pk_internal->capitalR1); + bi_free_ptr( pk_internal->capitalR0); + bi_free_ptr( pk_internal->capitalZ); + bi_free_ptr( pk_internal->capitalS); + bi_free_ptr( pk_internal->modulus); + free( pk_internal); +} + +/* free a TSS_DAA_PK structures */ +void +free_TSS_DAA_PK(TSS_DAA_PK *pk) +{ + int i; + + LogDebug("-> free_TSS_DAA_PK"); + free( pk->modulus); + free( pk->capitalS); + free( pk->capitalZ); + free( pk->capitalR0); + free( pk->capitalR1); + free( pk->gamma); + free( pk->capitalGamma); + free( pk->rho); + for( i=0; i<(int)pk->capitalYLength; i++) { + free( pk->capitalY[i]); + } + free( pk->capitalY); + free( pk->issuerBaseName); + free( pk); + LogDebug("<- free_TSS_DAA_PK"); + +} + +TPM_DAA_ISSUER * +convert2issuer_settings(TSS_DAA_PK_internal *pk_internal) +{ + TPM_DAA_ISSUER *result = (TPM_DAA_ISSUER *)malloc(sizeof(TPM_DAA_ISSUER)); + EVP_MD_CTX mdctx; + UINT32 length; + BYTE *array = (BYTE*)malloc((DAA_PARAM_SIZE_RSA_MODULUS+7)/8); + + LogDebug("convert2issuer_settings"); + EVP_MD_CTX_init(&mdctx); + // TAG + result->tag = htons( TPM_TAG_DAA_ISSUER); + // capitalR0 + EVP_DigestInit(&mdctx, DAA_PARAM_get_message_digest()); + + EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL); + bi_2_byte_array( array, + length = (bi_length( pk_internal->capitalR0)+7)/8, + pk_internal->capitalR0); + LogDebug("capitalR0 length=%d", length); + EVP_DigestUpdate(&mdctx, array, length); + EVP_DigestFinal_ex(&mdctx, (BYTE *)&(result->DAA_digest_R0), NULL); + // capitalR1 + EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL); + bi_2_byte_array( array, + length = (bi_length( pk_internal->capitalR1)+7)/8, + pk_internal->capitalR1); + LogDebug("capitalR1 length=%d", length); + EVP_DigestUpdate(&mdctx, array, length); + EVP_DigestFinal_ex(&mdctx, (BYTE *)&(result->DAA_digest_R1), NULL); + // capitalS (S0) + EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL); + bi_2_byte_array( array, + length = (bi_length( pk_internal->capitalS)+7)/8, + pk_internal->capitalS); + LogDebug("capitalS length=%d", length); + EVP_DigestUpdate(&mdctx, array, length); + EVP_DigestFinal_ex(&mdctx, (BYTE *)&(result->DAA_digest_S0), NULL); + // capitalSprime (S1) + EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL); + bi_2_byte_array( array, + length = (bi_length( pk_internal->capitalSprime)+7)/8, + pk_internal->capitalSprime); + LogDebug("capitalSprime length=%d", length); + EVP_DigestUpdate(&mdctx, array, length); + EVP_DigestFinal_ex(&mdctx, (BYTE *)&(result->DAA_digest_S1), NULL); + // modulus (n) + EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL); + bi_2_byte_array( array, + length = (bi_length( pk_internal->modulus)+7)/8, + pk_internal->modulus); + LogDebug("modulus length=%d", length); + EVP_DigestUpdate(&mdctx, array, length); + EVP_DigestFinal_ex(&mdctx, (BYTE *)&(result->DAA_digest_n), NULL); + // modulus (n) + EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL); + bi_2_byte_array( array, + length = (bi_length( pk_internal->capitalGamma)+7)/8, + pk_internal->capitalGamma); + LogDebug("capitalGamma length=%d", length); + EVP_DigestUpdate(&mdctx, array, length); + free(array); + EVP_DigestFinal_ex(&mdctx, (BYTE *)&(result->DAA_digest_gamma), NULL); + EVP_MD_CTX_cleanup(&mdctx); + // rho + bi_2_byte_array( (BYTE *)&(result->DAA_generic_q), 26, pk_internal->rho); + return result; +} + +BYTE * +issuer_2_byte_array(TPM_DAA_ISSUER *tpm_daa_issuer, int *length) +{ + UINT32 size = sizeof(UINT16) + ( 6 * TPM_SHA1_160_HASH_LEN) + 26; + BYTE * result = (BYTE *)malloc( sizeof(BYTE)*size); + UINT32 i = 0; + + memcpy( &result[i], &(tpm_daa_issuer->tag), sizeof(UINT16)); + i+=sizeof(UINT16); + memcpy( &result[i], &(tpm_daa_issuer->DAA_digest_R0), TPM_SHA1_160_HASH_LEN); + i+=TPM_SHA1_160_HASH_LEN; + memcpy( &result[i], &(tpm_daa_issuer->DAA_digest_R1), TPM_SHA1_160_HASH_LEN); + i+=TPM_SHA1_160_HASH_LEN; + memcpy( &result[i], &(tpm_daa_issuer->DAA_digest_S0), TPM_SHA1_160_HASH_LEN); + i+=TPM_SHA1_160_HASH_LEN; + memcpy( &result[i], &(tpm_daa_issuer->DAA_digest_S1), TPM_SHA1_160_HASH_LEN); + i+=TPM_SHA1_160_HASH_LEN; + memcpy( &result[i], &(tpm_daa_issuer->DAA_digest_n), TPM_SHA1_160_HASH_LEN); + i+=TPM_SHA1_160_HASH_LEN; + memcpy( &result[i], &(tpm_daa_issuer->DAA_digest_gamma), TPM_SHA1_160_HASH_LEN); + i+=TPM_SHA1_160_HASH_LEN; + memcpy( &result[i], &(tpm_daa_issuer->DAA_generic_q), 26); + *length = size; + return result; +} + +/******************************************************************************************** +* TSS_DAA_PK_PROOF +********************************************************************************************/ + +/* +* this function keep references on: +* - challenge (BYTE *) +* - response (bi_array_ptr *) +*/ +TSS_DAA_PK_PROOF_internal * +create_DAA_PK_PROOF(BYTE* const challenge, + const int length_challenge, + bi_array_ptr *response, + const int length_response) +{ + TSS_DAA_PK_PROOF_internal *pk_proof; + +#ifdef DAA_DEBUG + printf("create_DAA_PK_PROOF_internal\n"); +#endif + pk_proof = (TSS_DAA_PK_PROOF_internal *)malloc( sizeof(TSS_DAA_PK_PROOF_internal)); + pk_proof->challenge = challenge; + pk_proof->length_challenge = length_challenge; + pk_proof->response = response; + pk_proof->length_response = length_response; + return pk_proof; +} + +#if 0 +int +save_DAA_PK_PROOF_internal(FILE *file, TSS_DAA_PK_PROOF_internal *proof) +{ + int i; + +#ifdef DAA_DEBUG + printf("save_DAA_PK_PROOF_internal"); +#endif + fprintf(file, "%d # %s.length\n", proof->length_challenge, "challenge"); + fprintf(file, "%s\n", dump_byte_array( proof->length_challenge, + proof->challenge)); + fprintf(file, "%d # %s.length\n", proof->length_response, "response"); + for (i = 0; i < proof->length_response; i++) { + BI_SAVE_ARRAY( proof->response[i], file); + } + + return 0; +} + +/* load <proof> using <filename> */ +/* allocation of: */ +/* proof->challenge (BYTE*) */ +/* response (bi_array_ptr) */ +TSS_DAA_PK_PROOF_internal * +load_DAA_PK_PROOF_internal(FILE *file) +{ + TSS_DAA_PK_PROOF_internal *proof = + (TSS_DAA_PK_PROOF_internal *)malloc(sizeof(TSS_DAA_PK_PROOF_internal)); + char *read_buffer; + int i; + +#ifdef DAA_DEBUG + printf("load_DAA_PK_PROOF_internal"); +#endif + proof->length_challenge = read_int( file); + read_buffer = read_str( file); + proof->challenge = retrieve_byte_array( &(proof->length_challenge),read_buffer); + proof->length_response = read_int( file); + proof->response = (bi_array_ptr *)malloc( sizeof(bi_array_ptr) * proof->length_response); + for (i = 0; i < proof->length_response; i++) { + proof->response[i] = ALLOC_BI_ARRAY(); + BI_LOAD_ARRAY( proof->response[i], file); + } + return proof; +} +#endif + +TSS_DAA_PK_PROOF * +i_2_e_TSS_DAA_PK_PROOF(TSS_DAA_PK_PROOF_internal*pk_internal_proof, + void * (*daa_alloc)(size_t size, TSS_HOBJECT param), + TSS_HOBJECT param_alloc) +{ + TSS_DAA_PK_PROOF *pk_proof = + (TSS_DAA_PK_PROOF *)daa_alloc( sizeof(TSS_DAA_PK_PROOF), param_alloc); + int i, j; + int length_response2; + int length_response3; + + init_tss_version( pk_proof); + // CHALLENGE + pk_proof->challengeLength = pk_internal_proof->length_challenge; + pk_proof->challenge = (BYTE *)daa_alloc( pk_internal_proof->length_challenge, + param_alloc); + memcpy( pk_proof->challenge, pk_internal_proof->challenge, + pk_internal_proof->length_challenge); + // RESPONSES + pk_proof->responseLength = pk_internal_proof->length_response; + length_response2 = pk_internal_proof->response[0]->length; + pk_proof->responseLength2 = length_response2; + length_response3 = bi_nbin_size( + pk_internal_proof->response[0]->array[0]); + if( length_response3 & 1) length_response3++; // length_response3 should be paire + pk_proof->responseLength3 = length_response3; + pk_proof->response = (BYTE ***)daa_alloc( sizeof(BYTE **) * + pk_internal_proof->length_response, param_alloc); + for(i = 0; i < pk_internal_proof->length_response; i++) { + pk_proof->response[i] = (BYTE **)daa_alloc( sizeof(BYTE *) * length_response2, + param_alloc); + for( j = 0; j < length_response2; j++) { + (pk_proof->response[i])[j] = (BYTE *)malloc( + sizeof(BYTE) * length_response3); + bi_2_byte_array( pk_proof->response[i][j], + length_response3, + pk_internal_proof->response[i]->array[j]); + } + } + return pk_proof; +} + +TSS_DAA_PK_PROOF_internal * +e_2_i_TSS_DAA_PK_PROOF(TSS_DAA_PK_PROOF *pk_proof) +{ + int i, j, response_length2; + TSS_DAA_PK_PROOF_internal *pk_proof_internal = + (TSS_DAA_PK_PROOF_internal *)malloc( sizeof( TSS_DAA_PK_PROOF_internal)); + + // CHALLENGE + pk_proof_internal->length_challenge = pk_proof->challengeLength; +#ifdef DAA_DEBUG + fprintf(stderr, "issuer_length=%d\n", pk_proof_internal->length_challenge); +#endif + pk_proof_internal->challenge = (BYTE *)malloc( pk_proof_internal->length_challenge); + memcpy( pk_proof_internal->challenge, + pk_proof->challenge, + pk_proof_internal->length_challenge); + // RESPONSES + pk_proof_internal->length_response = pk_proof->responseLength; + response_length2 = pk_proof->responseLength2; + pk_proof_internal->response = + (bi_array_ptr *)malloc( sizeof(bi_array_ptr) * + pk_proof_internal->length_response); + for(i = 0; i<pk_proof_internal->length_response; i++) { + pk_proof_internal->response[i] = ALLOC_BI_ARRAY(); + bi_new_array2( pk_proof_internal->response[i], response_length2); + for( j = 0; j < response_length2; j++) { + pk_proof_internal->response[i]->array[j] = + get_bi( pk_proof->responseLength3, pk_proof->response[i][j]); + } + } + return pk_proof_internal; +} + + +/******************************************************************************************** +* TSS_DAA_JOIN_ISSUER_SESSION +********************************************************************************************/ + +TSS_DAA_JOIN_ISSUER_SESSION_internal * +create(TSS_DAA_PK_PROOF_internal *issuerKeyPair, + TPM_DAA_ISSUER *issuerAuthKey, + TSS_DAA_IDENTITY_PROOF *identityProof, + bi_ptr capitalUprime, + int daaCounter, + int nonceIssuerLength, + BYTE *nonceIssuer, + int nonceEncryptedLength, + BYTE *nonceEncrypted) +{ + TSS_DAA_JOIN_ISSUER_SESSION_internal *result = + (TSS_DAA_JOIN_ISSUER_SESSION_internal *)malloc( + sizeof(TSS_DAA_JOIN_ISSUER_SESSION_internal)); + + result->issuerAuthKey = issuerAuthKey; + result->issuerKeyPair = issuerKeyPair; + result->identityProof = identityProof; + result->capitalUprime = capitalUprime; + result->daaCounter = daaCounter; + result->nonceIssuerLength = nonceIssuerLength; + result->nonceIssuer = nonceIssuer; + result->nonceEncryptedLength = nonceEncryptedLength; + result->nonceEncrypted = nonceEncrypted; + return result; +} + + +/******************************************************************************************** + * TSS_DAA_SIGNATURE + ********************************************************************************************/ + +TSS_DAA_SIGNATURE_internal* +e_2_i_TSS_DAA_SIGNATURE(TSS_DAA_SIGNATURE* signature) +{ + TSS_DAA_SIGNATURE_internal *signature_intern = + (TSS_DAA_SIGNATURE_internal *)malloc( sizeof( TSS_DAA_SIGNATURE_internal)); + int i, length; + + signature_intern->zeta = bi_set_as_nbin( signature->zetaLength, signature->zeta); + signature_intern->capitalT = bi_set_as_nbin( signature->capitalTLength, + signature->capitalT); + signature_intern->challenge_length = signature->challengeLength; + signature_intern->challenge = (BYTE *)malloc( signature->challengeLength); + memcpy( signature_intern->challenge, + signature->challenge, + signature->challengeLength); + signature_intern->nonce_tpm_length = signature->nonceTpmLength; + signature_intern->nonce_tpm = (BYTE *)malloc( signature->nonceTpmLength); + memcpy( signature_intern->nonce_tpm, signature->nonceTpm, signature->nonceTpmLength); + signature_intern->sV = bi_set_as_nbin( signature->sVLength, signature->sV); + signature_intern->sF0 = bi_set_as_nbin( signature->sF0Length, signature->sF0); + signature_intern->sF1 = bi_set_as_nbin( signature->sF1Length, signature->sF1); + signature_intern->sE = bi_set_as_nbin( signature->sELength, signature->sE); + signature_intern->sA = (bi_array_ptr)malloc( sizeof( bi_array)); + bi_new_array2( signature_intern->sA, signature->sALength); + length = ( DAA_PARAM_SIZE_RANDOMIZED_ATTRIBUTES + 7) / 8; + for (i = 0; i < (int)signature->sALength; i++) { + signature_intern->sA->array[i] = bi_set_as_nbin( length, signature->sA[i]); + } + + return signature_intern; +} + +void +free_TSS_DAA_SIGNATURE_internal(TSS_DAA_SIGNATURE_internal *signature) +{ + bi_free_array( signature->sA); + bi_free_ptr( signature->sE); + bi_free_ptr( signature->sF1); + bi_free_ptr( signature->sF0); + bi_free_ptr( signature->sV); + free( signature->nonce_tpm); + free( signature->challenge); + bi_free_ptr( signature->capitalT); + bi_free_ptr( signature->zeta); + free( signature); +} + +#if 0 +/******************************************************************************************** + TSS_DAA_CRED_ISSUER +********************************************************************************************/ + +TSS_DAA_CRED_ISSUER * +load_TSS_DAA_CRED_ISSUER(FILE *file) +{ + TSS_DAA_CRED_ISSUER *credential = + (TSS_DAA_CRED_ISSUER *)malloc(sizeof(TSS_DAA_CRED_ISSUER)); + char *read_buffer; + int i, len; + + init_tss_version( credential); + credential->capitalALength = read_int( file); + read_buffer = read_str( file); + credential->capitalA = retrieve_byte_array( &(credential->capitalALength), + read_buffer); + credential->eLength = read_int( file); + read_buffer = read_str( file); + credential->e = retrieve_byte_array( &(credential->eLength),read_buffer); + credential->vPrimePrimeLength = read_int( file); + read_buffer = read_str( file); + credential->vPrimePrime = retrieve_byte_array(&(credential->vPrimePrimeLength), + read_buffer); + // attributes issuer + credential->attributesIssuerLength = read_int( file); + credential->attributesIssuer = malloc(credential->attributesIssuerLength*sizeof(BYTE*)); + for( i=0; i < (int)credential->attributesIssuerLength; i++) { + credential->attributesIssuer[i] = retrieve_byte_array( &len, read_buffer); + } + credential->cPrimeLength = read_int( file); + read_buffer = read_str( file); + credential->cPrime = retrieve_byte_array( &(credential->cPrimeLength),read_buffer); + credential->sELength = read_int( file); + read_buffer = read_str( file); + credential->sE = retrieve_byte_array( &(credential->sELength),read_buffer); + return credential; +} + +int +save_TSS_DAA_CRED_ISSUER(FILE *file, TSS_DAA_CRED_ISSUER *credential) +{ + int i; + + fprintf(file, "%d # %s.length\n", credential->capitalALength, "capitalA"); + fprintf(file, "%s\n", dump_byte_array( credential->capitalALength, + credential->capitalA)); + fprintf(file, "%d # %s.length\n", credential->eLength, "e"); + fprintf(file, "%s\n", dump_byte_array( credential->eLength, + credential->e)); + fprintf(file, "%d # %s.length\n", credential->vPrimePrimeLength, "vPrimePrime"); + fprintf(file, "%s\n", dump_byte_array( credential->vPrimePrimeLength, + credential->vPrimePrime)); + fprintf(file, "%d # %s\n", credential->attributesIssuerLength, "attributesIssuerLength"); + for( i=0; i < (int)credential->attributesIssuerLength; i++) { + fprintf(file, "%s\n", dump_byte_array( DAA_PARAM_SIZE_F_I / 8, + credential->attributesIssuer[i])); + + } + fprintf(file, "%d # %s.length\n", credential->cPrimeLength, "cPrime"); + fprintf(file, "%s\n", dump_byte_array( credential->cPrimeLength, + credential->cPrime)); + fprintf(file, "%d # %s.length\n", credential->sELength, "sE"); + fprintf(file, "%s\n", dump_byte_array( credential->sELength, + credential->sE)); + return 0; +} + + +/******************************************************************************************** + TSS_DAA_CREDENTIAL +********************************************************************************************/ + +TSS_DAA_CREDENTIAL * +load_TSS_DAA_CREDENTIAL(FILE *file) +{ + TSS_DAA_CREDENTIAL *credential = + (TSS_DAA_CREDENTIAL *)malloc(sizeof(TSS_DAA_CREDENTIAL)); + char *read_buffer; + int i, len; + TSS_DAA_PK_internal *pk_internal; + TSS_DAA_PK *pk; + + init_tss_version( credential); + credential->capitalALength = read_int( file); + read_buffer = read_str( file); + credential->capitalA = retrieve_byte_array( &(credential->capitalALength), + read_buffer); + credential->exponentLength = read_int( file); + read_buffer = read_str( file); + credential->exponent = retrieve_byte_array( &(credential->exponentLength), + read_buffer); + credential->vBar0Length = read_int( file); + read_buffer = read_str( file); + credential->vBar0 = retrieve_byte_array(&(credential->vBar0Length), + read_buffer); + credential->vBar1Length = read_int( file); + read_buffer = read_str( file); + credential->vBar1 = retrieve_byte_array(&(credential->vBar1Length), + read_buffer); + // attributes issuer + credential->attributesLength = read_int( file); + printf("attributesLength=%d\n", credential->attributesLength); + credential->attributes = malloc(credential->attributesLength * sizeof( BYTE *)); + for( i=0; i < (int)credential->attributesLength; i++) { + read_buffer = read_str( file); + credential->attributes[i] = retrieve_byte_array( &len, read_buffer); + if( len != DAA_PARAM_SIZE_F_I / 8) { + LogError("Error when parsing attributes"); + LogError("\tattribute length:%d", len); + LogError("\texpected length:%d", DAA_PARAM_SIZE_F_I / 8); + return NULL; + } + } + pk_internal = load_DAA_PK_internal( file); + pk = i_2_e_TSS_DAA_PK( pk_internal, &normal_malloc, (TSS_HOBJECT)NULL); + memcpy( &(credential->issuerPK), pk, sizeof(TSS_DAA_PK)); + free( pk); + free_TSS_DAA_PK_internal( pk_internal); + credential->tpmSpecificEncLength = read_int( file); + read_buffer = read_str( file); + credential->tpmSpecificEnc = retrieve_byte_array( &(credential->tpmSpecificEncLength), + read_buffer); + credential->daaCounter = read_int( file); + return credential; +} + +int +save_TSS_DAA_CREDENTIAL(FILE *file, + TSS_DAA_CREDENTIAL *credential) +{ + int i; + TSS_DAA_PK_internal *pk_internal; + + fprintf(file, "%d # %s.length\n", credential->capitalALength, "capitalA"); + fprintf(file, "%s\n", dump_byte_array( credential->capitalALength, + credential->capitalA)); + fprintf(file, "%d # %s.length\n", credential->exponentLength, "exponent"); + fprintf(file, "%s\n", dump_byte_array( credential->exponentLength, + credential->exponent)); + fprintf(file, "%d # %s.length\n", credential->vBar0Length, "vBar0"); + fprintf(file, "%s\n", dump_byte_array( credential->vBar0Length, + credential->vBar0)); + fprintf(file, "%d # %s.length\n", credential->vBar1Length, "vBar1"); + fprintf(file, "%s\n", dump_byte_array( credential->vBar1Length, + credential->vBar1)); + fprintf(file, "%d # %s\n", credential->attributesLength, "attributesLength"); + for( i=0; i < (int)credential->attributesLength; i++) { + fprintf(file, "%s\n", dump_byte_array( DAA_PARAM_SIZE_F_I / 8, + credential->attributes[i])); + } + pk_internal = e_2_i_TSS_DAA_PK( &(credential->issuerPK) ); + save_DAA_PK_internal( file, pk_internal); + free_TSS_DAA_PK_internal( pk_internal); + fprintf(file, "%d # %s.length\n", credential->tpmSpecificEncLength, "tpmSpecificEnc"); + fprintf(file, "%s\n", dump_byte_array( credential->tpmSpecificEncLength, + credential->tpmSpecificEnc)); + fprintf(file, "%d # daaCounter\n", credential->daaCounter); + return 0; +} +#endif +/******************************************************************************************** + TPM_DAA_ISSUER +********************************************************************************************/ + +void +free_TPM_DAA_ISSUER(TPM_DAA_ISSUER *tpm_daa_issuer) +{ + free(tpm_daa_issuer); +} diff --git a/src/tspi/daa/daa_verifier/test/Makefile.am b/src/tspi/daa/daa_verifier/test/Makefile.am new file mode 100644 index 0000000..aa02721 --- /dev/null +++ b/src/tspi/daa/daa_verifier/test/Makefile.am @@ -0,0 +1,7 @@ +bin_PROGRAMS = verifier_transaction + +verifier_transaction_SOURCES = ../verifier_transaction.c ../../daa_structs.c \ + ../../big_integer/bi_gmp.c ../../big_integer/bi_openssl.c ../../big_integer/bi.c \ + ../../../include/bi.h ../../../include/bi_openssl.h ../../../include/bi_gmp.h \ + ../../../include/list_.h ../../utils/list.c ../../../include/tss/tss.h ../../../include/daa_parameter.h \ + ../../../include/daa_structs.h diff --git a/src/tspi/daa/daa_verifier/verifier.c b/src/tspi/daa/daa_verifier/verifier.c new file mode 100644 index 0000000..ad7cef1 --- /dev/null +++ b/src/tspi/daa/daa_verifier/verifier.c @@ -0,0 +1,57 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "bi.h" +#include "daa_parameter.h" +#include "trousers/tss.h" +#include "spi_internal_types.h" +#include "spi_utils.h" +#include <trousers/trousers.h> +#include <obj.h> +#include "tsplog.h" +#include "tss/tcs.h" +#include "platform.h" + +#include "verifier.h" + +TSPICALL Tspi_DAA_VerifyInit_internal +( + TSS_HDAA hDAA, // in + UINT32* nonceVerifierLength, // out + BYTE** nonceVerifier, // out + UINT32 baseNameLength, // out + BYTE ** baseName // out +) { + TSS_RESULT result = TSS_SUCCESS; + TCS_CONTEXT_HANDLE tcsContext; + bi_ptr nounce = NULL; + + //TODO how to setup the baseName & baseNameLength + if( (result = obj_daa_get_tsp_context( hDAA, &tcsContext)) != TSS_SUCCESS) + goto close; + *nonceVerifierLength = DAA_PARAM_LENGTH_MESSAGE_DIGEST; + *nonceVerifier = calloc_tspi( tcsContext, DAA_PARAM_LENGTH_MESSAGE_DIGEST); + if (*nonceVerifier == NULL) { + LogError("malloc of %d bytes failed", DAA_PARAM_LENGTH_MESSAGE_DIGEST); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + nounce = bi_new_ptr(); + bi_urandom( nounce, DAA_PARAM_LENGTH_MESSAGE_DIGEST * 8); + bi_2_byte_array( *nonceVerifier, DAA_PARAM_LENGTH_MESSAGE_DIGEST, nounce); +close: + FREE_BI( nounce); + return result; +} diff --git a/src/tspi/daa/daa_verifier/verifier_transaction.c b/src/tspi/daa/daa_verifier/verifier_transaction.c new file mode 100644 index 0000000..1eecd43 --- /dev/null +++ b/src/tspi/daa/daa_verifier/verifier_transaction.c @@ -0,0 +1,873 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +// for message digest +#include <openssl/evp.h> + +#include "daa_structs.h" +#include "daa_parameter.h" +#include "trousers/tss.h" +#include "spi_internal_types.h" +#include "spi_utils.h" +#include <trousers/trousers.h> +#include <spi_utils.h> +#include <obj.h> +#include "tsplog.h" +#include "tss/tcs.h" +#include "verifier.h" + +#include "trousers/tss.h" +#include "spi_internal_types.h" +#include "spi_utils.h" + +#include "anonymity_revocation.h" + +DAA_VERIFIER_TRANSACTION *create_verifier_transaction( int length, char *base_name) { + DAA_VERIFIER_TRANSACTION *verifier_transaction = + malloc(sizeof(DAA_VERIFIER_TRANSACTION)); + + if (verifier_transaction == NULL) { + LogError("malloc of %d bytes failed", sizeof(DAA_VERIFIER_TRANSACTION)); + return NULL; + } + verifier_transaction->baseName = base_name; + verifier_transaction->baseName_length = length; + OpenSSL_add_all_digests(); + verifier_transaction->digest = DAA_PARAM_get_message_digest(); + return verifier_transaction; +} + +static int verifyNonce( BYTE *nonce_verifier, int length) { + //TODO check nonce_verifier with the current transaction nonce + return 1; +} + +BYTE *compute_bytes( int seedLength, BYTE *seed, int length, const EVP_MD *digest) { + EVP_MD_CTX mdctx; + int N; + BYTE *hash; + BYTE *result; + int i, big_indian_i, len_hash; + + result = (BYTE *)malloc( length); + if (result == NULL) { + LogError("malloc of %d bytes failed", length); + return NULL; + } + EVP_MD_CTX_init(&mdctx); + EVP_DigestInit_ex(&mdctx, digest, NULL); + len_hash = EVP_MD_size(digest); + N = length / len_hash; + hash = (BYTE *)malloc( len_hash); + if (hash == NULL) { + LogError("malloc of %d bytes failed", len_hash); + return NULL; + } + for( i=0; i<N; i++) { + EVP_DigestUpdate(&mdctx, seed, seedLength); + big_indian_i = htonl( i); + EVP_DigestUpdate(&mdctx, &big_indian_i, sizeof( int)); + EVP_DigestFinal_ex(&mdctx, &result[ i * len_hash], NULL); + EVP_DigestInit_ex(&mdctx, digest, NULL); + } + // fill up the rest of the array (i=N) + EVP_DigestUpdate(&mdctx, seed, seedLength); + big_indian_i = htonl( i); + EVP_DigestUpdate(&mdctx, &big_indian_i, sizeof( int)); + EVP_DigestFinal(&mdctx, hash, NULL); + // copy the rest: base_nameLength % len_hash bytes + memcpy( &result[ i * len_hash], hash, length - N * len_hash); + free( hash); + return result; +} + +/* from DAAUtil */ +bi_ptr project_into_group_gamma( bi_ptr base, TSS_DAA_PK_internal *issuer_pk) { + bi_t exponent; bi_new( exponent); + bi_ptr capital_gamma = issuer_pk->capitalGamma; + bi_ptr rho = issuer_pk->rho; + bi_ptr zeta = bi_new_ptr(); + + if( capital_gamma == NULL || + rho == NULL || + zeta == NULL) return NULL; + // exponent = capital_gamma - 1 + bi_sub( exponent, capital_gamma, bi_1); + // exponent = exponent / rho + bi_div( exponent, exponent, rho); + // zeta = ( base ^ exponent) % capital_gamma + LogDebug("project_into_group_gamma: rho [%ld]:%s", + bi_nbin_size( rho), bi_2_hex_char( rho)); + LogDebug("project_into_group_gamma: base[%ld]:%s", + bi_nbin_size( base), bi_2_hex_char( base)); + LogDebug("project_into_group_gamma: exponent [%ld]:%s", + bi_nbin_size( exponent), bi_2_hex_char( exponent)); + LogDebug("project_into_group_gamma: capitalGamma[%ld]:%s", + bi_nbin_size( capital_gamma), + bi_2_hex_char( capital_gamma)); + bi_mod_exp( zeta, base, exponent, capital_gamma); + LogDebug("project_into_group_gamma: result:%s", bi_2_hex_char( zeta)); + bi_free( exponent); + return zeta; +} + +bi_ptr compute_zeta( int nameLength, unsigned char *name, TSS_DAA_PK_internal *issuer_pk) { + BYTE *bytes; + bi_ptr base; + bi_ptr result; + + LogDebug("compute_zeta: %d [%s] pk:%x", nameLength, name, (int)issuer_pk); + bytes = compute_bytes( nameLength, + name, + DAA_PARAM_LENGTH_MFG1_GAMMA, + DAA_PARAM_get_message_digest()); + if( bytes == NULL) return NULL; + base = bi_set_as_nbin( DAA_PARAM_LENGTH_MFG1_GAMMA, bytes); + if( base == NULL) return NULL; + LogDebug("base: %ld [%s]", bi_nbin_size( base), bi_2_hex_char( base)); + result = project_into_group_gamma( base, issuer_pk); + if( result == NULL) return NULL; + bi_free_ptr( base); + free( bytes); + LogDebug("return zeta:%s\n", bi_2_hex_char( result)); + return result; +} + +bi_ptr compute_parameterized_gamma(int k, TSS_DAA_PK_internal *issuer_pk) { + int length; + int hashLength = bi_nbin_size( issuer_pk->gamma) + sizeof(int); + BYTE *hash; + int big_indian_k = htonl( k); + BYTE *bytes; + bi_ptr value, result; + + hash = (BYTE *)malloc( hashLength); + if (hash == NULL) { + LogError("malloc of %d bytes failed", hashLength); + return NULL; + } + // hash[0-3] = big_indian(k) + memcpy( hash, &big_indian_k, sizeof(int)); + // hash[4-end] = issuer_pk->gamma + bi_2_nbin1( &length, &hash[sizeof(int)], issuer_pk->gamma); + // allocation + bytes = compute_bytes( hashLength, hash, + DAA_PARAM_LENGTH_MFG1_GAMMA, + DAA_PARAM_get_message_digest()); + if( bytes == NULL) return NULL; + // allocation + value = bi_set_as_nbin( DAA_PARAM_LENGTH_MFG1_GAMMA, bytes); + if( value == NULL) return NULL; + result = project_into_group_gamma( value, issuer_pk); // allocation + if (result == NULL) { + LogError("malloc of %d bytes failed", hashLength); + return NULL; + } + bi_free_ptr( value); + free( bytes); + return result; +} + +inline bi_ptr apply_challenge( bi_ptr value, bi_ptr delta, bi_ptr c, bi_ptr capital_gamma) { + bi_ptr delta_tilde = bi_new_ptr(); + bi_t c_negate; + + if( delta_tilde == NULL) return NULL; + bi_new( c_negate); + bi_set( c_negate, c); + bi_negate( c_negate); + // delta_tilde = ( delta ^ (-c)) % capital_gamma + bi_mod_exp( delta_tilde, delta, c_negate, capital_gamma); + bi_free( c_negate); + // delta_tilde = (delta_tilde * value) % capital_gamma + return bi_mod( delta_tilde, bi_mul( delta_tilde, delta_tilde, value), capital_gamma); +} + +DAA_VERIFIER_TRANSACTION *createTransaction(int baseName_length, BYTE* baseName) { + DAA_VERIFIER_TRANSACTION *result = + (DAA_VERIFIER_TRANSACTION *)malloc( sizeof(DAA_VERIFIER_TRANSACTION)); + + if (result == NULL) { + LogError("malloc of %d bytes failed", sizeof(DAA_VERIFIER_TRANSACTION)); + return NULL; + } + result->baseName = baseName; + result->baseName_length = baseName_length; + return result; +} + +void update( EVP_MD_CTX *mdctx, char *name, bi_ptr integer, int bitLength) { + int length = bitLength / 8; + BYTE buffer[length]; + + bi_2_byte_array( buffer, length, integer); + LogDebug("[update] %s:%s", name, dump_byte_array( length, buffer)); + EVP_DigestUpdate(mdctx, buffer, length); +} + +BYTE *compute_sign_challenge_host( + int *result_length, + EVP_MD *digest, + TSS_DAA_PK_internal *issuer_pk, + int nonce_verifierLength, + BYTE *nonce_verifier, + int selected_attributes2commitLength, + TSS_DAA_SELECTED_ATTRIB **selected_attributes2commit, + int is_anonymity_revocation_enabled, + bi_ptr zeta, + bi_ptr capital_t, + bi_ptr capital_tilde, + int attribute_commitmentsLength, + TSS_DAA_ATTRIB_COMMIT_internal **attribute_commitments, + TSS_DAA_ATTRIB_COMMIT_internal **attribute_commitment_proofs, + bi_ptr capital_nv, + bi_ptr capital_tilde_v, + CS_PUBLIC_KEY *anonymity_revocator_pk, + CS_ENCRYPTION_RESULT *encryption_result_rand, + CS_ENCRYPTION_RESULT *encryption_result_proof +) { + EVP_MD_CTX mdctx; + int i, length; + unsigned int big_indian; + BYTE *buffer; + int length_gamma_modulus; + BYTE *buffer1; + + LogDebug("issuer_pk basename[%d]:%s", + issuer_pk->issuerBaseNameLength, + dump_byte_array( issuer_pk->issuerBaseNameLength, + issuer_pk->issuerBaseName)); + LogDebug("nonce_verifier[%d]:%s", + nonce_verifierLength, + dump_byte_array( nonce_verifierLength, nonce_verifier)); + LogDebug("selected_attributes2commitLength:%d", selected_attributes2commitLength); + LogDebug("is_anonymity_revocation_enabled:%d", is_anonymity_revocation_enabled); + LogDebug("zeta[%ld]:%s", bi_nbin_size( zeta), bi_2_hex_char( zeta)); + LogDebug("capital_t[%ld]:%s", bi_nbin_size( capital_t), bi_2_hex_char( capital_t)); + LogDebug("capital_tilde[%ld]:%s", + bi_nbin_size( capital_tilde), + bi_2_hex_char( capital_tilde)); + LogDebug("attribute_commitmentsLength:%d", attribute_commitmentsLength); + LogDebug("attribute_commitments:%d", (int)attribute_commitments); + LogDebug("attribute_commitment_proofs:%d", (int)attribute_commitment_proofs); + LogDebug("capital_nv[%ld]:%s", bi_nbin_size( capital_nv), bi_2_hex_char( capital_nv)); + LogDebug("capital_tilde_v[%ld]:%s", + bi_nbin_size( capital_tilde_v), + bi_2_hex_char( capital_tilde_v)); + LogDebug("anonymity_revocator_pk:%d", (int)anonymity_revocator_pk); + LogDebug("encryption_result_rand:%d", (int)encryption_result_rand); + LogDebug("encryption_result_proof:%d", (int)encryption_result_proof); + + EVP_MD_CTX_init(&mdctx); + EVP_DigestInit_ex(&mdctx, digest, NULL); + // update with encoded PK + buffer = encoded_DAA_PK_internal( &length, issuer_pk); + if( buffer == NULL) return NULL; + LogDebug("encoded issuer_pk[%d]:%s", length, dump_byte_array( length, buffer)); + EVP_DigestUpdate(&mdctx, buffer , length); + free( buffer); + // nonce verifier + EVP_DigestUpdate(&mdctx, nonce_verifier , nonce_verifierLength); + // length Commitments + big_indian = attribute_commitmentsLength; + EVP_DigestUpdate(&mdctx, &big_indian, sizeof(int)); + // Anonymity enabled + big_indian = is_anonymity_revocation_enabled; + EVP_DigestUpdate(&mdctx, &big_indian, sizeof(int)); + + update( &mdctx, "zeta", zeta, DAA_PARAM_SIZE_MODULUS_GAMMA); + update( &mdctx, "capitalT", capital_t, DAA_PARAM_SIZE_RSA_MODULUS); + update( &mdctx, "capitalTTilde", capital_tilde, DAA_PARAM_SIZE_RSA_MODULUS); + + length_gamma_modulus = DAA_PARAM_SIZE_MODULUS_GAMMA / 8; + buffer = (BYTE *)malloc( length_gamma_modulus);// allocation + if (buffer == NULL) { + LogError("malloc of %d bytes failed", length_gamma_modulus); + return NULL; + } + if( selected_attributes2commitLength > 0) { + for( i=0; i<selected_attributes2commitLength; i++) { + buffer1 = to_bytes_TSS_DAA_SELECTED_ATTRIB_internal( + &length, + selected_attributes2commit[i]); + EVP_DigestUpdate(&mdctx, buffer1, length); + free( buffer1); + bi_2_byte_array( buffer, + length_gamma_modulus, + attribute_commitments[i]->beta); + EVP_DigestUpdate(&mdctx, + buffer, + length_gamma_modulus); + bi_2_byte_array( buffer, + length_gamma_modulus, + attribute_commitment_proofs[i]->beta); + EVP_DigestUpdate(&mdctx, + buffer, + length_gamma_modulus); + } + } + if( !is_anonymity_revocation_enabled) { + // Nv, N~v + bi_2_byte_array( buffer, length_gamma_modulus, capital_nv); + EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus); + bi_2_byte_array( buffer, length_gamma_modulus, capital_tilde_v); + EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus); + } else { + bi_2_byte_array( buffer, length_gamma_modulus, anonymity_revocator_pk->eta); + EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus); + bi_2_byte_array( buffer, length_gamma_modulus, anonymity_revocator_pk->lambda1); + EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus); + bi_2_byte_array( buffer, length_gamma_modulus, anonymity_revocator_pk->lambda2); + EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus); + bi_2_byte_array( buffer, length_gamma_modulus, anonymity_revocator_pk->lambda3); + EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus); + bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_rand->c1); + EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus); + bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_rand->c2); + EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus); + bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_rand->c3); + EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus); + bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_rand->c4); + EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus); + bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_proof->c1); + EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus); + bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_proof->c2); + EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus); + bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_proof->c3); + EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus); + bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_proof->c4); + EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus); + } + free(buffer); + buffer = (BYTE *)malloc(EVP_MD_size(digest)); // allocation + if (buffer == NULL) { + LogError("malloc of %d bytes failed", EVP_MD_size(digest)); + return NULL; + } + EVP_DigestFinal_ex(&mdctx, buffer, result_length); + EVP_MD_CTX_cleanup(&mdctx); + LogDebug("compute_sign_challenge_host[%d]:%s", + *result_length, + dump_byte_array( *result_length, buffer)); + return buffer; +} + +inline int is_element_gamma( bi_ptr capital_nv, TSS_DAA_PK_internal *issuer_pk) { + bi_ptr tmp1 = bi_new_ptr(); + int result; + + // ( ( capital_nv ^ issuer_pk->rho ) % issuer_pk->capitalGamma ) == 1 + result = bi_equals( bi_mod_exp( tmp1, + capital_nv, + issuer_pk->rho, + issuer_pk->capitalGamma), + bi_1); + bi_free_ptr( tmp1); + return result; +} + +/* implementation derived from isValid (VerifierTransaction.java) */ +TSPICALL Tspi_DAA_VerifySignature_internal +( TSS_HDAA hDAA, // in + TSS_DAA_SIGNATURE signature_ext, // in + TSS_HKEY hPubKeyIssuer, // in + TSS_DAA_SIGN_DATA sign_data, // in + UINT32 attributesLength, // in + BYTE **attributes, // in + UINT32 nonce_verifierLength, // out + BYTE *nonce_verifier, // out + UINT32 base_nameLength, // out + BYTE *base_name, // out + TSS_BOOL *isCorrect // out +) { + int i, j; + DAA_VERIFIER_TRANSACTION *verifier_transaction = NULL; + TSS_DAA_ATTRIB_COMMIT *commitments; + TSS_DAA_PK_internal *issuer_pk; + TSS_DAA_SIGNATURE_internal *signature = NULL; + bi_ptr tmp1; + bi_array_ptr sA; + bi_ptr n = NULL; + bi_ptr c = NULL; + bi_ptr capital_gamma = NULL; + bi_ptr zeta_2_verify = NULL; + bi_ptr capital_z = NULL; + bi_array_ptr capital_R = NULL; + bi_ptr product_r = NULL; + bi_ptr exp = NULL; + bi_ptr capital_THat = NULL; + bi_ptr beta_tilde = NULL; + bi_ptr gamma_i = NULL; + bi_ptr capital_nv = NULL; + bi_ptr capital_ntilde_v = NULL; + bi_ptr pseudonym_projected = NULL; + bi_ptr s_tau = NULL; + bi_ptr delta_tilde1 = NULL; + bi_ptr delta_tilde2 = NULL; + bi_ptr delta_tilde3 = NULL; + bi_ptr delta_tilde4 = NULL; + bi_ptr attribute_i; + TSS_DAA_PSEUDONYM_PLAIN *pseudonym_plain; + CS_ENCRYPTION_RESULT *pseudonym_enc = NULL; + CS_ENCRYPTION_RESULT *pseudonym_encryption_proof = NULL; + TSS_DAA_PSEUDONYM_ENCRYPTED_internal *sig_pseudonym_encrypted = NULL; + CS_ENCRYPTION_RESULT_RANDOMNESS *result_random = NULL; + CS_ENCRYPTION_RESULT *encryption_result = NULL; + TSS_DAA_ATTRIB_COMMIT_internal **commitment_proofs = NULL; + TCS_CONTEXT_HANDLE tcsContext; + TSS_RESULT result = TSS_SUCCESS; + EVP_MD_CTX mdctx; + int length_ch, len_hash, bits; + BYTE *ch = NULL, *hash = NULL; + TSS_BOOL *indices; + + tmp1 = bi_new_ptr(); + if( tmp1 == NULL) { + LogError("malloc of BI <%s> failed", "tmp1"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + *isCorrect = FALSE; + if( (result = obj_daa_get_tsp_context( hDAA, &tcsContext)) != TSS_SUCCESS) + goto close; + // allocation of issuer_pk + issuer_pk = e_2_i_TSS_DAA_PK( (TSS_DAA_PK *)hPubKeyIssuer); + if( issuer_pk == NULL) { + LogError("malloc of TSS_DAA_PK_internal failed"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + // allocation of signature + signature = e_2_i_TSS_DAA_SIGNATURE( &signature_ext); + if( signature == NULL) { + LogError("malloc of TSS_DAA_SIGNATURE_internal failed"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + commitments = signature_ext.attributeCommitments; + // TODO verify consistency of sig.getSA() with selectedAttributes,.. + sA = signature->sA; + if( sA->length != (int)attributesLength) { + LogError("Verifier Error: lengths of attributes and sA must be equal"); + result = TSS_E_BAD_PARAMETER; + goto close; + } + for ( i = 0; i < (int)attributesLength; i++) { + if ( (attributes[i] == NULL && bi_equals( sA->array[i], bi_0)) || + (attributes[i] != NULL && !bi_equals( sA->array[i], bi_0))) { + LogError( "Verifier Error: illegal argument content in attributes\ + and sA[%d]", i); + result = TSS_E_BAD_PARAMETER; + goto close; + } + } + // TODO: implement verify nonce + if ( verifyNonce(nonce_verifier, nonce_verifierLength) == 0) { + LogError("Verifier Error: nonce invalid"); + result = TSS_E_INTERNAL_ERROR; + goto close; + } + n = issuer_pk->modulus; + c = bi_set_as_nbin( signature->challenge_length, signature->challenge); + capital_gamma = issuer_pk->capitalGamma; + if( base_name != NULL) { // isRandomBaseName + zeta_2_verify = compute_zeta( base_nameLength, base_name, issuer_pk); + if( bi_equals( signature->zeta, zeta_2_verify) == 0) { + LogError("Verifier Error: Verification of zeta failed - Step 1"); + result = TSS_E_INTERNAL_ERROR; + goto close; + } + } + LogDebug( "step 2"); + capital_z = issuer_pk->capitalZ; + capital_R = issuer_pk->capitalY; + product_r = bi_new_ptr(); + if( product_r == NULL) { + LogError("malloc of BI <%s> failed", "product_r"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_set( product_r, bi_1); // product_r = 1 + for( i=0; i<(int)attributesLength; i++) { + if( attributes[i] != NULL) { + // allocation + attribute_i = bi_set_as_nbin( DAA_PARAM_SIZE_F_I / 8, attributes[i]); + if( attribute_i == NULL) { + LogError("malloc of %d bytes failed", DAA_PARAM_SIZE_F_I / 8); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + // tmp1 = (capital_R[i] ^ attributes[i]) mod n + bi_mod_exp( tmp1, capital_R->array[i], attribute_i, n); + // product_r = product_r * tmp1 + bi_mul( product_r, product_r, tmp1); + // product_r = product_r mod n + bi_mod( product_r, product_r, n); + bi_free_ptr( attribute_i); + } + } + exp = bi_new_ptr(); + if( exp == NULL) { + LogError("malloc of BI <%s> failed", "product_r"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + capital_THat = bi_new_ptr(); + // tmp1 = product_r invmod n + bi_invert_mod( tmp1, product_r, n); + // capital_THat = capital_z * tmp1 + bi_mul( capital_THat, capital_z, tmp1); + // capital_THat = capital_THat % n + bi_mod( capital_THat, capital_THat, n); + // capital_THat = (capital_THat ^ (-c)) mod n = ( 1 / (capital_That ^ c) ) % n + bi_mod_exp( capital_THat, capital_THat, c, n); + bi_invert_mod( capital_THat, capital_THat, n); + // tmp1 = c << (SizeExponentCertificate - 1) + bi_shift_left( tmp1, c, DAA_PARAM_SIZE_EXPONENT_CERTIFICATE - 1); + // exp = signature->sE + tmp1 + bi_add( exp, signature->sE, tmp1); + // tmp1 = (signature->capitalT ^ exp) mod n + bi_mod_exp( tmp1, signature->capitalT, exp, n); + // capital_THat = ( capital_THat * tmp1 ) % n + bi_mul( capital_THat, capital_THat, tmp1); + bi_mod( capital_THat, capital_THat, n); + // tmp1=( issuer_pk->capitalR0 ^ signature->sF0) % n + bi_mod_exp( tmp1, issuer_pk->capitalR0, signature->sF0, n); + // capital_THat = ( capital_THat * tmp1 ) % n + bi_mul( capital_THat, capital_THat, tmp1); + bi_mod( capital_THat, capital_THat, n); + // tmp1=( issuer_pk->capitalR1 ^ signature->sF1) % n + bi_mod_exp( tmp1, issuer_pk->capitalR1, signature->sF1, n); + // capital_THat = ( capital_THat * tmp1 ) % n + bi_mul( capital_THat, capital_THat, tmp1); + bi_mod( capital_THat, capital_THat, n); + // tmp1=( issuer_pk->capitalS ^ signature->sV) % n + bi_mod_exp( tmp1, issuer_pk->capitalS, signature->sV, n); + // capital_THat = ( capital_THat * tmp1 ) % n + bi_mul( capital_THat, capital_THat, tmp1); + bi_mod( capital_THat, capital_THat, n); + + bi_set( product_r, bi_1); // product_r = 1 + for( i=0; i<(int)attributesLength; i++) { + if( attributes[i] == NULL) { + // tmp1=(capital_R->array[i] ^ sA->array[i]) % n + bi_mod_exp( tmp1, capital_R->array[i], sA->array[i], n); + // product_r = ( product_r * tmp1 ) % n + bi_mul( product_r, product_r, tmp1); + bi_mod( product_r, product_r, n); + } + } + // capital_THat = (capital_THat * product_r) % n + bi_mod( capital_THat, bi_mul( tmp1, capital_THat, product_r), n); + LogDebug("Step 3 - Commitments"); + + //TODO when enabling the commitment feature, verifier_transaction should be set + #ifdef ANONYMITY_REVOCATION + if( verifier_transaction != NULL && + verifier_transaction->selected_attributes2commitLength > 0) { + commitment_proofs = (TSS_DAA_ATTRIB_COMMIT_internal **) + malloc(verifier_transaction->selected_attributes2commitLength * + sizeof(TSS_DAA_ATTRIB_COMMIT_internal*)); + if (commitment_proofs == NULL) { + LogError("malloc of %d bytes failed", + verifier_transaction->selected_attributes2commitLength * + sizeof(TSS_DAA_ATTRIB_COMMIT_internal*)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + for( j=0; j<verifier_transaction->selected_attributes2commitLength; j++) { + if( bi_cmp( commitments[j].sMu, issuer_pk->rho) >= 0 || + bi_cmp_si( commitments[j].sMu, 0) < 0) { + LogError("sMu >= rho || sMu < 0"); + result = TSS_E_INTERNAL_ERROR; + goto close; + } + beta_tilde = bi_new_ptr(); + if( beta_tilde == NULL) { + LogError("malloc of BI <%s> failed", "beta_tilde"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_set( tmp1, c); + bi_negate( tmp1); + // beta_tilde=(commitments[j]->beta ^ (-c)) % capitalGamma + bi_mod_exp( beta_tilde, commitments[j]->beta, tmp1, capital_gamma); + // tmp1=(issuer_pk->gamma ^ commitments[j]->sMu) % capital_gamma + bi_mod_exp( tmp1, issuer_pk->gamma, commitments[j]->sMu, capital_gamma); + // beta_tilde=beta_tilde * tmp1 + bi_mul( beta_tilde, beta_tilde, tmp1); + // beta_tilde=beta_tilde % capital_gamma + bi_mod( beta_tilde, beta_tilde, capital_gamma); + indices = (verifier_transaction->selected_attributes2commit[j])-> + indicesList; + if( verifier_transaction->selected_attributes2commit[j]-> + indicesListLength != (UINT32)(issuer_pk->capitalY->length) ) { + LogError("indicesList of selected_attribs[%d] (%d) \ +and issuer_pk are not consistent (%d)\n", + j, + verifier_transaction->selected_attributes2commit[j]-> + indicesListLength, + issuer_pk->capitalY->length); + result = TSS_E_INTERNAL_ERROR; + goto close; + } + for( i=0; i<issuer_pk->capitalY->length; i++) { + if( indices[i]) { + gamma_i = compute_parameterized_gamma( i, issuer_pk); + if( gamma_i == NULL) { + LogError("malloc of BI <%s> failed", "gamma_i"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + // tmp1=(gamma_i ^ sA[j]) % capital_gamma + bi_mod_exp( tmp1, gamma_i, sA->array[i], capital_gamma); + // beta_tilde=beta_tilde * tmp1 + bi_mul( beta_tilde, beta_tilde, tmp1); + // beta_tilde=beta_tilde % capital_gamma + bi_mod( beta_tilde, beta_tilde, capital_gamma); + } + } + commitment_proofs[j] = create_TSS_DAA_ATTRIB_COMMIT( beta_tilde, NULL); + } + } + #endif + LogDebug("Step 4 - Pseudonym"); + capital_nv = bi_new_ptr(); + if( capital_nv == NULL) { + LogError("malloc of BI <%s> failed", "capital_nv"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + capital_ntilde_v = bi_new_ptr(); + if( capital_ntilde_v == NULL) { + LogError("malloc of BI <%s> failed", "capital_ntilde_v"); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + bi_shift_left( tmp1, signature->sF1, DAA_PARAM_SIZE_F_I); + bi_add( exp, signature->sF0, tmp1); + pseudonym_projected = bi_new_ptr(); + // pseudonym_projected = (signature->zeta ^ exp) % capital_gamma + bi_mod_exp( pseudonym_projected, signature->zeta, exp, capital_gamma); + pseudonym_enc = NULL; + pseudonym_encryption_proof = NULL; + //TODO when enabling the commitment feature, verifier_transaction should be set + if( verifier_transaction == NULL || + verifier_transaction->is_anonymity_revocation_enabled ==0) { + // anonymity revocation not enabled + pseudonym_plain = (TSS_DAA_PSEUDONYM_PLAIN *)signature_ext.signedPseudonym; + capital_nv = bi_set_as_nbin( pseudonym_plain->capitalNvLength, + pseudonym_plain->capitalNv); +//TODO + // capital_ntilde_v = ( capital_nv ^ ( - c) ) % capital_gamma + // = ( 1 / (capital_nv ^ c) % capital_gamma) % capital_gamma + bi_mod_exp( tmp1, capital_nv, c, capital_gamma); + bi_invert_mod( capital_ntilde_v, tmp1, capital_gamma); + // capital_ntilde_v = ( capital_ntilde_v * pseudonym_projected ) % capital_gamma + bi_mul(capital_ntilde_v, capital_ntilde_v, pseudonym_projected); + bi_mod( capital_ntilde_v, capital_ntilde_v, capital_gamma); + } else { +#ifdef ANONYMITY_REVOCATION + // anonymity revocation enabled + sig_pseudonym_encrypted = (TSS_DAA_PSEUDONYM_ENCRYPTED_internal *)pseudonym; + s_tau = sig_pseudonym_encrypted->sTau; + pseudonym_enc = sig_pseudonym_encrypted->cs_enc_result; + // Note: It verifies if s_tau <= rho + result_random = compute_ecryption_proof( + pseudonym_projected, + pseudonym_enc->c1, + pseudonym_enc->c2, + pseudonym_enc->c3, + s_tau, + verifier_transaction->anonymity_revocator_pk, issuer_pk, + verifier_transaction->anonymity_revocation_condition, + verifier_transaction->anonymity_revocation_condition_length, + DAA_PARAM_get_message_digest() ); + encryption_result = result_random->result; + delta_tilde1 = apply_challenge( encryption_result->c1, + pseudonym_enc->c1, + c, + capital_gamma); + delta_tilde2 = apply_challenge( encryption_result->c2, + pseudonym_enc->c2, + c, + capital_gamma); + delta_tilde3 = apply_challenge( encryption_result->c3, + pseudonym_enc->c3, + c, + capital_gamma); + delta_tilde4 = apply_challenge( encryption_result->c4, + pseudonym_enc->c4, + c, + capital_gamma); + pseudonym_encryption_proof = create_CS_ENCRYPTION_RESULT( delta_tilde1, + delta_tilde2, + delta_tilde3, + delta_tilde4); +#endif + } + + // TODO: Step 5 - Callback + LogDebug("Step 5 - Callback"); + + LogDebug("Step 6 - Hash"); + ch = compute_sign_challenge_host( + &length_ch, + DAA_PARAM_get_message_digest(), + issuer_pk, + nonce_verifierLength, + nonce_verifier, + 0, // verifier_transaction->selected_attributes2commitLength, + NULL, //verifier_transaction->selected_attributes2commit, + 0, // verifier_transaction->is_anonymity_revocation_enabled, + signature->zeta, + signature->capitalT, + capital_THat, + 0, //signature_ext.attributeCommitmentsLength, + NULL, // signature_ext.attributeCommitments, + commitment_proofs, + capital_nv, + capital_ntilde_v, + NULL, // verifier_transaction->anonymity_revocator_pk, + pseudonym_enc, + pseudonym_encryption_proof); + LogDebug("calculation of c: ch[%d]%s", length_ch, dump_byte_array( length_ch, ch)); + LogDebug("calculation of c: nonce_tpm[%d]%s", + signature->nonce_tpm_length, + dump_byte_array( signature->nonce_tpm_length, signature->nonce_tpm)); + LogDebug("calculation of c: sign_data.payloadFlag[%d]%x", 1, sign_data.payloadFlag); + LogDebug("calculation of c: signdata.payload[%d]%s", + sign_data.payloadLength, + dump_byte_array( sign_data.payloadLength, sign_data.payload)); + EVP_MD_CTX_init(&mdctx); + EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL); + EVP_DigestUpdate(&mdctx, ch, length_ch); + EVP_DigestUpdate(&mdctx, signature->nonce_tpm, signature->nonce_tpm_length); + len_hash = EVP_MD_size( DAA_PARAM_get_message_digest()); + hash = (BYTE *)malloc( len_hash);// allocation + if (hash == NULL) { + LogError("malloc of %d bytes failed", len_hash); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + EVP_DigestFinal_ex(&mdctx, hash, NULL); + EVP_DigestInit_ex(&mdctx, DAA_PARAM_get_message_digest(), NULL); + EVP_DigestUpdate(&mdctx, hash, EVP_MD_size( DAA_PARAM_get_message_digest())); + EVP_DigestUpdate(&mdctx, &sign_data.payloadFlag, 1); + EVP_DigestUpdate(&mdctx, sign_data.payload, sign_data.payloadLength); + len_hash = EVP_MD_size( DAA_PARAM_get_message_digest()); + free( hash); + hash = (BYTE *)malloc( len_hash);// allocation + if (hash == NULL) { + LogError("malloc of %d bytes failed", len_hash); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + EVP_DigestFinal(&mdctx, hash, NULL); + + if( signature->challenge_length != len_hash || + memcmp( signature->challenge, hash, len_hash) != 0) { + LogError( "Verification of c failed - Step 6.c.i"); + LogError(" - challenge[%d] : %s", + signature->challenge_length, + dump_byte_array( signature->challenge_length, signature->challenge)); + LogError(" - hash[%d] : %s", + len_hash, + dump_byte_array( len_hash, hash)); + result = TSS_E_INTERNAL_ERROR; + goto close; + } + if( verifier_transaction == NULL || + !verifier_transaction->is_anonymity_revocation_enabled) { + // Nv element <gamma> ? + if( !is_element_gamma( capital_nv, issuer_pk) ) { + LogError( "Verification of Nv failed - Step 4.b.i"); + result = TSS_E_INTERNAL_ERROR; + goto close; + } + } else { + // are delta1-4 element <gamma> ? + if( !( is_element_gamma( pseudonym_enc->c1, issuer_pk) && + is_element_gamma( pseudonym_enc->c2, issuer_pk) && + is_element_gamma( pseudonym_enc->c3, issuer_pk) && + is_element_gamma( pseudonym_enc->c4, issuer_pk))) { + LogError( "Verification of delta1-4 failed - Step 4.c.i"); + result = TSS_E_INTERNAL_ERROR; + goto close; + } + } + // zeta element <gamma> + if( !is_element_gamma( signature->zeta, issuer_pk)) { + LogError( "Verification of zeta failed - Step 4.b/c.i"); + result = TSS_E_INTERNAL_ERROR; + goto close; + } + bits = DAA_PARAM_SIZE_F_I + DAA_PARAM_SAFETY_MARGIN + + DAA_PARAM_SIZE_MESSAGE_DIGEST + 1; + if( bi_length( signature->sF0) > bits) { + LogError("Verification of sF0 failed - Step 6.c.ii"); + result = TSS_E_INTERNAL_ERROR; + goto close; + } + if( bi_length( signature->sF1) > bits) { + LogError("Verification of sF1 failed - Step 6.c.ii"); + result = TSS_E_INTERNAL_ERROR; + goto close; + } + // attributes extension + for( i=0; i<sA->length; i++) { + if( sA->array[i] != NULL && bi_length(sA->array[i]) > bits) { + LogError( "Verification of sA[%d] failed - Step 6.c.ii", i); + result = TSS_E_INTERNAL_ERROR; + goto close; + } + } + bits = DAA_PARAM_SIZE_INTERVAL_EXPONENT_CERTIFICATE + + DAA_PARAM_SAFETY_MARGIN + DAA_PARAM_SIZE_MESSAGE_DIGEST + 1; + if( bi_length( signature->sE) > bits) { + LogError("Verification of sE failed - Step 6.c.iii"); + result = TSS_E_INTERNAL_ERROR; + goto close; + } + // step 4 + // TODO: implement revocation list + *isCorrect = TRUE; +close: + bi_free_ptr( tmp1); + if( ch != NULL) free( ch); + if( hash != NULL) free( hash); + free_TSS_DAA_PK_internal( issuer_pk); + free_TSS_DAA_SIGNATURE_internal( signature); + // n not allocated, refere to issuer_pk->modulus + FREE_BI( c); + // capital_gamma not allocated, refere to issuer_pk->capitalGamma + FREE_BI( zeta_2_verify); + // capital_z not allocated, refere to issuer_pk->capitalZ + // capital_R not allocated, refere to issuer_pk->capitalY + FREE_BI( product_r); + FREE_BI( exp); + FREE_BI( capital_THat); + // beta_tilde kept on TSS_DAA_ATTRIB_COMMIT + FREE_BI( gamma_i); + FREE_BI( capital_nv); + FREE_BI( capital_ntilde_v); + FREE_BI( pseudonym_projected); + FREE_BI( s_tau); + // delta_tilde1 kept on CS_ENCRYPTION_RESULT + // delta_tilde2 kept on CS_ENCRYPTION_RESULT + // delta_tilde3 kept on CS_ENCRYPTION_RESULT + // delta_tilde4 kept on CS_ENCRYPTION_RESULT + return result; +} diff --git a/src/tspi/daa/test_sign.c b/src/tspi/daa/test_sign.c new file mode 100644 index 0000000..2b13791 --- /dev/null +++ b/src/tspi/daa/test_sign.c @@ -0,0 +1,238 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include "daa_structs.h" +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "spi_internal_types.h" +#include "spi_utils.h" +#include "obj.h" +#include "tsplog.h" +#include "daa_parameter.h" +#include "verifier.h" +#include "platform.h" + +// for RSA Key +#include <openssl/rsa.h> + +#define DEFAULT_CREDENTIAL_FILENAME "credential.txt" +#define DEFAULT_OWN_PASSWD "OWN_PWD" + +int print_usage(char *exec) { + fprintf(stderr, "usage: %s\n", exec); + fprintf(stderr, + "\t-m,\t--message\n\t\tif define, the data is signed using this message\n\ +\t\totherwise an AIK will be generated and used\n"); + fprintf(stderr, + "\t-pw,\t--passwd\n\t\ttpm owner password (default: %s)\n", + DEFAULT_OWN_PASSWD); + fprintf(stderr, + "\t-cr,\t--credential\n\t\tcredential filename (default: %s)\n", + DEFAULT_CREDENTIAL_FILENAME); + return -1; +} + +int main(int argc, char *argv[]) { + TSS_HCONTEXT hContext; + TSS_RESULT result; + TSS_HTPM hTPM; + TSS_HPOLICY hPolicy; + char *credential_filename = DEFAULT_CREDENTIAL_FILENAME; + UINT32 nonceVerifierLength; + BYTE *nonceVerifier; + TSS_HDAA hDAA; + TSS_DAA_CREDENTIAL *hDaaCredential; + TSS_DAA_SIGN_DATA signData; + TSS_DAA_SIGNATURE daaSignature; + TSS_DAA_SELECTED_ATTRIB revealAttributes; + char *szTpmPasswd = DEFAULT_OWN_PASSWD; + char *message = NULL; + BYTE **attributes = NULL; + FILE *file; + char *param; + int i, length, rv; + bi_ptr random = NULL; + TSS_BOOL isCorrect; + EVP_MD_CTX mdctx; + TSS_HKEY hKEY; + + init_tss_version( &signData); + init_tss_version( &daaSignature); + init_tss_version( &revealAttributes); + i = 1; + while( i < argc) { + param = argv[ i]; + if ( strcmp( param, "-m") == 0 || strcmp( param, "--message") == 0) { + i++; + if( i == argc) return print_usage( argv[0]); + message = argv[i]; + } else if( strcmp( param, "-cr") == 0 || strcmp( param, "--credential") == 0){ + i++; + if( i == argc) return print_usage( argv[0]); + credential_filename = argv[i]; + } else if( strcmp( param, "-pw") == 0 || strcmp( param, "--passwd") == 0){ + i++; + if( i == argc) return print_usage( argv[0]); + szTpmPasswd = argv[i]; + } else { + fprintf(stderr, "%s:unrecognized option `%s'\n", argv[0], param); + return print_usage( argv[0]); + } + i++; + } + bi_init( NULL); + printf("Loading credential: %s ", credential_filename); + file = fopen( credential_filename, "r"); + if( (hDaaCredential = load_TSS_DAA_CREDENTIAL( file)) == 0) { + LogError( "[test_join]: Error when loading \'%s\': %s\n", + credential_filename, + strerror( errno)); + result = TSS_E_FAIL; + goto out_close; + } + fclose( file); + printf("Done\n"); + + // Create Context + LogDebug("Create Context"); + result = Tspi_Context_Create( &hContext ); + if ( result != TSS_SUCCESS ) + { + LogError( "Tspi_Context_Create %d\n", result ); + goto out; + } + // Connect to Context + result = Tspi_Context_Connect( hContext, NULL ); + if ( result != TSS_SUCCESS) goto out_close; + printf("\nConnect to the context: %X\n", hContext); + + if( (result = Tspi_Context_GetTpmObject( hContext, &hTPM)) != TSS_SUCCESS) + goto out_close; + // Get the correct policy using the TPM ownership PASSWD + if( (result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hPolicy)) != TSS_SUCCESS) + goto out_close; + if( (result = Tspi_Policy_SetSecret( hPolicy, + TSS_SECRET_MODE_PLAIN, + strlen( szTpmPasswd), + szTpmPasswd)) != TSS_SUCCESS) + goto out_close; + LogDebug("Tspi_Policy_SetSecret hPolicy received;%d", hPolicy); + + //Create Object + result = obj_daa_add( hContext, &hDAA); + if (result != TSS_SUCCESS) { + LogError("Tspi_Context_CreateObject:%d", result); + Tspi_Context_Close(hContext); + LogError("%s: %s", argv[0], err_string(result)); + exit(result); + } + LogDebug("created DAA object:%X", hDAA); + + // TODO: verifier base name ?? + result = Tspi_DAA_VerifyInit( + hDAA, // in + &nonceVerifierLength, // out + &nonceVerifier, // out + 0, //baseNameLength, // out + NULL //baseName // out + ); + if (result != TSS_SUCCESS) goto out_close; + LogDebug("Verify Init return nonceVerifier [%s]", + dump_byte_array( nonceVerifierLength, nonceVerifier)); + + create_TSS_DAA_SELECTED_ATTRIB( &revealAttributes, 5, 0, 1, 1, 0, 0); + + // create the TSS_DAA_SIGN_DATA struct + // .selector: 0 -> payload contains a handle to an AIK + // 1 -> payload contains a hashed message + if( message != NULL) { + signData.selector = TSS_FLAG_DAA_SIGN_MESSAGE_HASH; + signData.payloadFlag = TSS_FLAG_DAA_SIGN_MESSAGE_HASH; + EVP_DigestInit(&mdctx, DAA_PARAM_get_message_digest()); + EVP_DigestUpdate(&mdctx, (BYTE *)message, strlen( message)); + signData.payloadLength = EVP_MD_CTX_size(&mdctx); + signData.payload = (BYTE *)malloc( EVP_MD_CTX_size(&mdctx)); + EVP_DigestFinal(&mdctx, signData.payload, NULL); + } else { + signData.selector = TSS_FLAG_DAA_SIGN_IDENTITY_KEY; + result = Tspi_Context_CreateObject( + hContext, // in + TSS_OBJECT_TYPE_RSAKEY, // in + TSS_KEY_SIZE_2048, // in + &hKEY // out + ); + if( result != TSS_SUCCESS) goto out_close; + + } + + result = Tspi_TPM_DAA_Sign( + hDAA, // in + hTPM, // in + (TSS_HKEY)hDaaCredential, // in + revealAttributes, // in + 0, // verifierBaseNameLength, // in + NULL, // verifierBaseName, // in + nonceVerifierLength, // in + nonceVerifier, // in + signData, // in + &daaSignature // out + ); + if (result != TSS_SUCCESS) goto out_close; + LogDebug("TPM_DAA_Sign return daaSignature [%s]", + dump_byte_array( nonceVerifierLength, nonceVerifier)); + + // generate attributes list but without copying the not revealed ones + attributes = malloc( sizeof(BYTE *) * hDaaCredential->attributesLength); + for( i=0; i < (int)(hDaaCredential->attributesLength); i++) { + if( revealAttributes.indicesList[i]) { + attributes[i] = (BYTE *)malloc( DAA_PARAM_SIZE_F_I / 8); + memcpy( attributes[i], + hDaaCredential->attributes[i], + DAA_PARAM_SIZE_F_I / 8); + } else { + attributes[i] = NULL; + } + } + + result = Tspi_DAA_VerifySignature( + hDAA, // in + daaSignature, // in + (TSS_HKEY)&(hDaaCredential->issuerPK), // in + signData, // in + hDaaCredential->attributesLength, // in + attributes, // in + nonceVerifierLength, // in + nonceVerifier, // in + 0, //baseNameLength, //in + NULL, // in + &isCorrect // out + ); + printf("Signature correct:%s\n", ( isCorrect ? "yes" : "no")); + +out_close: + if( attributes != NULL) { + for( i=0; i<(int)hDaaCredential->attributesLength; i++) { + if( attributes[i] != NULL) free( attributes[i]); + } + free( attributes); + } + if( random != NULL) bi_free_ptr( random); + Tspi_Context_FreeMemory( hContext, NULL ); + Tspi_Context_Close( hContext ); +out: + bi_release(); + LogDebug("THE END result=%d:%s",result, err_string( result) );; + return result; +} + diff --git a/src/tspi/daa/utils/list.c b/src/tspi/daa/utils/list.c new file mode 100644 index 0000000..634129b --- /dev/null +++ b/src/tspi/daa/utils/list.c @@ -0,0 +1,66 @@ + +/* +* Licensed Materials - Property of IBM +* +* trousers - An open source TCG Software Stack +* +* (C) Copyright International Business Machines Corp. 2006 +* +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <list.h> + +#include "tsplog.h" + +list_ptr list_new( void) { + list_ptr list = (list_ptr)malloc( sizeof( list_struct)); + + if( list == NULL) return NULL; + list->head = NULL; + return list; +} + +void list_add(list_ptr list, void *obj) { + list->current = (node_t *) malloc (sizeof(struct _list_t)); + if (list->current == NULL) { + LogError("[list_add] malloc of %d bytes failed", sizeof(struct _list_t)); + return; + } + if( list->head == NULL) { + list->head = list->current; + } else + list->previous->next = list->current; + list->current->obj = obj; + list->current->next = NULL; + list->previous = list->current; +} + +void list_dump(list_ptr list) { + node_t *current; + + if( list->head == NULL) // if head has not been altered + puts("no data"); // list is empty + else { + current = list->head; // go to first node + do { + printf("%d\n", (int)current->obj); // print value at current node + current = current->next; // traverse through the list + } while(current != NULL); // until current node is NULL + } +} + +void list_freeall(list_ptr list) { + node_t *current = list->head; // go to first node + node_t *next; + + if( list->head != NULL) { + current = list->head; // go to first node + do { + next = current->next; + free(current); + current = next; + } while(current != NULL); // until current node is NULL + } +} diff --git a/src/tspi/gtk/callbacks.c b/src/tspi/gtk/callbacks.c new file mode 100644 index 0000000..86570fc --- /dev/null +++ b/src/tspi/gtk/callbacks.c @@ -0,0 +1,163 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004 + * + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gtk/gtk.h> +#include <string.h> + +#undef TRUE +#undef FALSE + +#include "callbacks.h" +#include "interface.h" +#include "support.h" +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "tsplog.h" + + +/* Callbacks for the simple password dialog */ + +void +on_inputdialog1_destroy(GtkObject *object, struct userdata *user_data) +{ + gtk_widget_destroy(user_data->window); + gtk_main_quit(); +} + + +void +on_dialog1_close(GtkDialog *dialog, struct userdata *user_data) +{ + gtk_widget_destroy(user_data->window); + gtk_main_quit(); +} + + +void +on_cancelbutton1_clicked(GtkButton *button, struct userdata *user_data) +{ + LogDebugFn(); + gtk_widget_destroy(user_data->window); + user_data->string_len = 0; + gtk_main_quit(); +} + + +void +on_okbutton1_clicked(GtkButton *button, struct userdata *user_data) +{ + const gchar *entry_text = gtk_entry_get_text (GTK_ENTRY(user_data->entry)); + + LogDebugFn(); + user_data->string = (char *)Trspi_Native_To_UNICODE((BYTE *)entry_text, + &user_data->string_len); + gtk_widget_destroy(user_data->window); + + gtk_main_quit(); +} + + +gboolean +enter_event(GtkWidget *widget, struct userdata *user_data) +{ + const gchar *entry_text = gtk_entry_get_text (GTK_ENTRY(user_data->entry)); + + LogDebugFn(); + user_data->string = (char *)Trspi_Native_To_UNICODE((BYTE *)entry_text, + &user_data->string_len); + gtk_widget_destroy(user_data->window); + + gtk_main_quit(); + return TRUE; +} + + +/* Callbacks for the new password dialog */ +void +on_entryPassword_activate(GtkEntry *entry, struct userdata *user_data) +{ + const gchar *entryPass_text = gtk_entry_get_text (GTK_ENTRY(user_data->entryPass)); + const gchar *entryConf_text = gtk_entry_get_text (GTK_ENTRY(user_data->entryConf)); + int len = strlen(entryConf_text); + + if (strlen(entryConf_text) == strlen(entryPass_text)) { + if (!memcmp(entryPass_text, entryConf_text, len)) { + user_data->string = (char *)Trspi_Native_To_UNICODE((BYTE *)entryConf_text, + &user_data->string_len); + gtk_widget_destroy(user_data->window); + gtk_main_quit(); + + LogDebugFn("string len ptr: %p, value = %u", &user_data->string_len, + user_data->string_len); + return; + } + } + + gtk_widget_grab_focus(user_data->entryConf); +} + +void +on_entryConfirm_activate(GtkEntry *entry, struct userdata *user_data) +{ + const gchar *entryPass_text = gtk_entry_get_text (GTK_ENTRY(user_data->entryPass)); + const gchar *entryConf_text = gtk_entry_get_text (GTK_ENTRY(user_data->entryConf)); + unsigned len = strlen(entryConf_text); + + if (strlen(entryConf_text) == strlen(entryPass_text)) { + if (!memcmp(entryPass_text, entryConf_text, len)) { + user_data->string = (char *)Trspi_Native_To_UNICODE((BYTE *)entryConf_text, + &user_data->string_len); + gtk_widget_destroy(user_data->window); + gtk_main_quit(); + + LogDebugFn("string len ptr: %p, value = %u", &user_data->string_len, + user_data->string_len); + return; + } + } + + gtk_widget_grab_focus(user_data->entryPass); +} + +void +on_cancelbutton2_clicked(GtkButton *button, struct userdata *user_data) +{ + LogDebugFn(); + gtk_widget_destroy(user_data->window); + user_data->string_len = 0; + gtk_main_quit(); +} + +void +on_okbutton2_clicked(GtkButton *button, struct userdata *user_data) +{ + const gchar *entryPass_text = gtk_entry_get_text (GTK_ENTRY(user_data->entryPass)); + const gchar *entryConf_text = gtk_entry_get_text (GTK_ENTRY(user_data->entryConf)); + unsigned len = strlen(entryConf_text); + + if (strlen(entryConf_text) == strlen(entryPass_text)) { + if (!memcmp(entryPass_text, entryConf_text, len)) { + user_data->string = (char *)Trspi_Native_To_UNICODE((BYTE *)entryConf_text, + &user_data->string_len); + gtk_widget_destroy(user_data->window); + gtk_main_quit(); + + LogDebugFn("string len ptr: %p, value = %u", &user_data->string_len, + user_data->string_len); + return; + } + } + + gtk_widget_grab_focus(user_data->entryPass); +} diff --git a/src/tspi/gtk/callbacks.h b/src/tspi/gtk/callbacks.h new file mode 100644 index 0000000..1fca617 --- /dev/null +++ b/src/tspi/gtk/callbacks.h @@ -0,0 +1,58 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004 + * + */ + +#ifndef _CALLBACKS_H_ +#define _CALLBACKS_H_ + +#include <gtk/gtk.h> + +#include "interface.h" + +/* Callbacks for the simple text imput dialog */ + +void +on_dialog1_close (GtkDialog *dialog, + struct userdata *user_data); + +void +on_cancelbutton1_clicked (GtkButton *button, + struct userdata *user_data); + +void +on_okbutton1_clicked (GtkButton *button, + struct userdata *user_data); + +gboolean +enter_event (GtkWidget *widget, + struct userdata *user_data); + +void +on_inputdialog1_destroy (GtkObject *object, + struct userdata *user_data); + +/* Callbacks for the new password dialog */ + +void +on_entryPassword_activate (GtkEntry *entry, + struct userdata *user_data); + +void +on_entryConfirm_activate (GtkEntry *entry, + struct userdata *user_data); + +void +on_cancelbutton2_clicked (GtkButton *button, + struct userdata *user_data); + +void +on_okbutton2_clicked (GtkButton *button, + struct userdata *user_data); + +#endif diff --git a/src/tspi/gtk/interface.c b/src/tspi/gtk/interface.c new file mode 100644 index 0000000..c295beb --- /dev/null +++ b/src/tspi/gtk/interface.c @@ -0,0 +1,299 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004, 2005 + * + */ + +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <string.h> +#include <stdio.h> + +#include <gdk/gdkkeysyms.h> +#include <gtk/gtk.h> + +#include "callbacks.h" +#include "interface.h" +#include "support.h" + +#define GLADE_HOOKUP_OBJECT(component,widget,name) \ + g_object_set_data_full (G_OBJECT (component), name, \ + gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref) + +#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \ + g_object_set_data (G_OBJECT (component), name, widget) + +GtkWidget* +create_password_dialog (struct userdata *ud, char *message) +{ + GtkWidget *dialog1; + GtkWidget *dialog_vbox1; + GtkWidget *vbox1; + GtkWidget *entry; + GtkWidget *alignment1; + GtkWidget *table2; + GtkWidget *label1; + GtkWidget *alignment2; + GtkWidget *table1; + GtkWidget *dialog_action_area1; + GtkWidget *cancelbutton1; + GtkWidget *okbutton1; + GtkTooltips *tooltips; + + tooltips = gtk_tooltips_new (); + + dialog1 = gtk_dialog_new (); + gtk_widget_set_size_request (dialog1, 300, 150); + //gtk_tooltips_set_tip (tooltips, dialog1, _("This is a box for entering dialogue"), NULL); + gtk_window_set_title (GTK_WINDOW (dialog1), _("TSS Password")); + //gtk_window_set_title (GTK_WINDOW (dialog1), message); + gtk_window_set_position (GTK_WINDOW (dialog1), GTK_WIN_POS_CENTER); + gtk_window_set_default_size (GTK_WINDOW (dialog1), 300, 150); + + dialog_vbox1 = GTK_DIALOG (dialog1)->vbox; + gtk_widget_show (dialog_vbox1); + + vbox1 = gtk_vbox_new (TRUE, 0); + gtk_widget_show (vbox1); + gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox1, TRUE, TRUE, 0); + + alignment1 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_show (alignment1); + gtk_box_pack_start (GTK_BOX (vbox1), alignment1, FALSE, FALSE, 0); + + table2 = gtk_table_new (3, 3, FALSE); + gtk_widget_show (table2); + gtk_container_add (GTK_CONTAINER (alignment1), table2); + + //label1 = gtk_label_new (_("Please enter a password, or not.")); + label1 = gtk_label_new (message); + gtk_widget_show (label1); + gtk_table_attach (GTK_TABLE (table2), label1, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label1), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (label1), 0, 0.5); + + alignment2 = gtk_alignment_new (0.5, 0.5, 1, 1); + gtk_widget_show (alignment2); + gtk_box_pack_start (GTK_BOX (vbox1), alignment2, TRUE, TRUE, 0); + + table1 = gtk_table_new (2, 3, FALSE); + gtk_widget_show (table1); + gtk_container_add (GTK_CONTAINER (alignment2), table1); + + entry = gtk_entry_new (); + gtk_widget_show (entry); + gtk_table_attach (GTK_TABLE (table1), entry, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + //gtk_tooltips_set_tip (tooltips, entry, _("This is where you enter the characters of your password, using the computer input device of your choice."), NULL); + gtk_entry_set_max_length (GTK_ENTRY (entry), 255); + gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE); + + dialog_action_area1 = GTK_DIALOG (dialog1)->action_area; + gtk_widget_show (dialog_action_area1); + gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END); + + cancelbutton1 = gtk_button_new_from_stock ("gtk-cancel"); + gtk_widget_show (cancelbutton1); + gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), cancelbutton1, GTK_RESPONSE_CANCEL); + GTK_WIDGET_SET_FLAGS (cancelbutton1, GTK_CAN_DEFAULT); + //gtk_tooltips_set_tip (tooltips, cancelbutton1, _("Depress this button in order to indicate that you would like to cancel the submitting of authorization data at this time."), NULL); + + okbutton1 = gtk_button_new_from_stock ("gtk-ok"); + gtk_widget_show (okbutton1); + gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), okbutton1, GTK_RESPONSE_OK); + GTK_WIDGET_SET_FLAGS (okbutton1, GTK_CAN_DEFAULT); + //gtk_tooltips_set_tip (tooltips, okbutton1, _("Depress this button in order to indicate that you have completed the entry of your authorization data."), NULL); + + /* We need to pass the window in to destroy it */ + ud->window = dialog1; + /* Here we need a pointer to the entry to grab the text out of it */ + ud->entry = entry; + + g_signal_connect ((gpointer) dialog1, "close", + G_CALLBACK (on_dialog1_close), + ud); + + g_signal_connect ((gpointer) dialog1, "destroy", + G_CALLBACK (on_inputdialog1_destroy), + ud); + + g_signal_connect ((gpointer) entry, "activate", + G_CALLBACK (enter_event), + ud); + + g_signal_connect ((gpointer) cancelbutton1, "clicked", + G_CALLBACK (on_cancelbutton1_clicked), + ud); + + g_signal_connect ((gpointer) okbutton1, "clicked", + G_CALLBACK (on_okbutton1_clicked), + ud); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (dialog1, dialog1, "dialog1"); + GLADE_HOOKUP_OBJECT_NO_REF (dialog1, dialog_vbox1, "dialog_vbox1"); + GLADE_HOOKUP_OBJECT (dialog1, vbox1, "vbox1"); + GLADE_HOOKUP_OBJECT (dialog1, alignment1, "alignment1"); + GLADE_HOOKUP_OBJECT (dialog1, table2, "table2"); + GLADE_HOOKUP_OBJECT (dialog1, label1, "label1"); + GLADE_HOOKUP_OBJECT (dialog1, alignment2, "alignment2"); + GLADE_HOOKUP_OBJECT (dialog1, table1, "table1"); + GLADE_HOOKUP_OBJECT (dialog1, entry, "entry"); + GLADE_HOOKUP_OBJECT_NO_REF (dialog1, dialog_action_area1, "dialog_action_area1"); + GLADE_HOOKUP_OBJECT (dialog1, cancelbutton1, "cancelbutton1"); + GLADE_HOOKUP_OBJECT (dialog1, okbutton1, "okbutton1"); + GLADE_HOOKUP_OBJECT_NO_REF (dialog1, tooltips, "tooltips"); + + return dialog1; +} + +GtkWidget* +create_new_password_dialog (struct userdata *ud, char *message) +{ + GtkWidget *dialog1; + GtkWidget *dialog_vbox1; + GtkWidget *vbox1; + GtkWidget *table2; + GtkWidget *label7; + GtkWidget *table1; + GtkWidget *label5; + GtkWidget *label6; + GtkWidget *entryPassword; + GtkWidget *entryConfirm; + GtkWidget *dialog_action_area1; + GtkWidget *cancelbutton2; + GtkWidget *okbutton2; + + dialog1 = gtk_dialog_new (); + gtk_widget_set_size_request (dialog1, 300, 150); + gtk_window_set_title (GTK_WINDOW (dialog1), "TSS Password"); + //gtk_window_set_title (GTK_WINDOW (dialog1), message); + + dialog_vbox1 = GTK_DIALOG (dialog1)->vbox; + gtk_widget_show (dialog_vbox1); + + vbox1 = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox1); + gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox1, TRUE, TRUE, 0); + + table2 = gtk_table_new (3, 3, FALSE); + gtk_widget_show (table2); + gtk_box_pack_start (GTK_BOX (vbox1), table2, TRUE, TRUE, 0); + + //label7 = gtk_label_new (_("Please enter a new password below.")); + label7 = gtk_label_new (message); + gtk_widget_show (label7); + gtk_table_attach (GTK_TABLE (table2), label7, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label7), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (label7), 0, 0.5); + + table1 = gtk_table_new (5, 5, FALSE); + gtk_widget_show (table1); + gtk_box_pack_start (GTK_BOX (vbox1), table1, TRUE, TRUE, 0); + + label5 = gtk_label_new (_("Password:")); + gtk_widget_show (label5); + gtk_table_attach (GTK_TABLE (table1), label5, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label5), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (label5), 0, 0.5); + + label6 = gtk_label_new (_("Confirm:")); + gtk_widget_show (label6); + gtk_table_attach (GTK_TABLE (table1), label6, 1, 2, 3, 4, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_label_set_justify (GTK_LABEL (label6), GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment (GTK_MISC (label6), 0, 0.5); + + entryPassword = gtk_entry_new (); + gtk_widget_show (entryPassword); + gtk_table_attach (GTK_TABLE (table1), entryPassword, 3, 4, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_entry_set_max_length (GTK_ENTRY (entryPassword), 255); + gtk_entry_set_visibility (GTK_ENTRY (entryPassword), FALSE); + + entryConfirm = gtk_entry_new (); + gtk_widget_show (entryConfirm); + gtk_table_attach (GTK_TABLE (table1), entryConfirm, 3, 4, 3, 4, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + gtk_entry_set_max_length (GTK_ENTRY (entryConfirm), 255); + gtk_entry_set_visibility (GTK_ENTRY (entryConfirm), FALSE); + + dialog_action_area1 = GTK_DIALOG (dialog1)->action_area; + gtk_widget_show (dialog_action_area1); + gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END); + + cancelbutton2 = gtk_button_new_from_stock ("gtk-cancel"); + gtk_widget_show (cancelbutton2); + gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), cancelbutton2, GTK_RESPONSE_CANCEL); + GTK_WIDGET_SET_FLAGS (cancelbutton2, GTK_CAN_DEFAULT); + + okbutton2 = gtk_button_new_from_stock ("gtk-ok"); + gtk_widget_show (okbutton2); + gtk_dialog_add_action_widget (GTK_DIALOG (dialog1), okbutton2, GTK_RESPONSE_OK); + GTK_WIDGET_SET_FLAGS (okbutton2, GTK_CAN_DEFAULT); + + /* We need to pass the window in to destroy it */ + ud->window = dialog1; + /* Here we need a pointer to the entries to grab text out of them */ + ud->entryPass = entryPassword; + ud->entryConf = entryConfirm; + + g_signal_connect ((gpointer) dialog1, "destroy", + G_CALLBACK (on_inputdialog1_destroy), + ud); + + g_signal_connect ((gpointer) entryPassword, "activate", + G_CALLBACK (on_entryPassword_activate), + ud); + g_signal_connect ((gpointer) entryConfirm, "activate", + G_CALLBACK (on_entryConfirm_activate), + ud); + g_signal_connect ((gpointer) cancelbutton2, "clicked", + G_CALLBACK (on_cancelbutton2_clicked), + ud); + g_signal_connect ((gpointer) okbutton2, "clicked", + G_CALLBACK (on_okbutton2_clicked), + ud); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (dialog1, dialog1, "dialog1"); + GLADE_HOOKUP_OBJECT_NO_REF (dialog1, dialog_vbox1, "dialog_vbox1"); + GLADE_HOOKUP_OBJECT (dialog1, vbox1, "vbox1"); + GLADE_HOOKUP_OBJECT (dialog1, table2, "table2"); + GLADE_HOOKUP_OBJECT (dialog1, label7, "label7"); + GLADE_HOOKUP_OBJECT (dialog1, table1, "table1"); + GLADE_HOOKUP_OBJECT (dialog1, label5, "label5"); + GLADE_HOOKUP_OBJECT (dialog1, label6, "label6"); + GLADE_HOOKUP_OBJECT (dialog1, entryPassword, "entryPassword"); + GLADE_HOOKUP_OBJECT (dialog1, entryConfirm, "entryConfirm"); + GLADE_HOOKUP_OBJECT_NO_REF (dialog1, dialog_action_area1, "dialog_action_area1"); + GLADE_HOOKUP_OBJECT (dialog1, cancelbutton2, "cancelbutton2"); + GLADE_HOOKUP_OBJECT (dialog1, okbutton2, "okbutton2"); + + return dialog1; +} + + diff --git a/src/tspi/gtk/interface.h b/src/tspi/gtk/interface.h new file mode 100644 index 0000000..9950fe7 --- /dev/null +++ b/src/tspi/gtk/interface.h @@ -0,0 +1,30 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004 + * + */ + +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifndef _INTERFACE_H_ +#define _INTERFACE_H_ + +struct userdata { + char *string; + unsigned string_len; + GtkWidget *window; + GtkWidget *entry; + GtkWidget *entryPass; + GtkWidget *entryConf; +}; + +GtkWidget* create_password_dialog (struct userdata *, char *); +GtkWidget* create_new_password_dialog (struct userdata *, char *); + +#endif diff --git a/src/tspi/gtk/main.c b/src/tspi/gtk/main.c new file mode 100644 index 0000000..3b76402 --- /dev/null +++ b/src/tspi/gtk/main.c @@ -0,0 +1,117 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004 + * + */ + +/* + * Initial main.c file generated by Glade. Edit as required. + * Glade will not overwrite this file. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <sys/types.h> +#include <string.h> + +#include <gtk/gtk.h> + +#undef TRUE +#undef FALSE + +#include "trousers/tss.h" +#include "tsplog.h" + +#include "interface.h" +#include "support.h" + +/* + * DisplayPINWindow() + * + * Popup the dialog to collect an existing password. + * + * string - buffer that the password will be passed back to caller in + * popup - UTF-8 string to be displayed in the title bar of the dialog box + * + */ +TSS_RESULT +DisplayPINWindow(BYTE *string, UINT32 *string_len, BYTE *popup) +{ + GtkWidget *dialog1; + struct userdata ud; + + ud.string_len = 0; + +#ifdef ENABLE_NLS + bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); +#endif + + gtk_set_locale(); + gtk_init_check((int *)NULL, (char ***)NULL); + + LogDebug("address of string_len: %p", &ud.string_len); + dialog1 = create_password_dialog(&ud, (char *)popup); + gtk_widget_show(dialog1); + + gtk_main(); + + if (ud.string_len) { + memcpy(string, ud.string, ud.string_len); + memset(ud.string, 0, ud.string_len); + free(ud.string); + } + *string_len = ud.string_len; + + return TSS_SUCCESS; +} + +/* + * DisplayNewPINWindow() + * + * Popup the dialog to collect a new password. + * + * string - buffer that the password will be passed back to caller in + * popup - UTF-8 string to be displayed in the title bar of the dialog box + * + */ +TSS_RESULT +DisplayNewPINWindow(BYTE *string, UINT32 *string_len, BYTE *popup) +{ + GtkWidget *dialog1; + struct userdata ud; + + ud.string_len = 0; + +#ifdef ENABLE_NLS + bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); +#endif + + gtk_set_locale(); + gtk_init_check((int *)NULL, (char ***)NULL); + + LogDebug("address of string_len: %p", &ud.string_len); + dialog1 = create_new_password_dialog(&ud, (char *)popup); + gtk_widget_show(dialog1); + + gtk_main(); + + if (ud.string_len) { + memcpy(string, ud.string, ud.string_len); + memset(ud.string, 0, ud.string_len); + free(ud.string); + } + *string_len = ud.string_len; + + return TSS_SUCCESS; +} + diff --git a/src/tspi/gtk/support.c b/src/tspi/gtk/support.c new file mode 100644 index 0000000..6ce3870 --- /dev/null +++ b/src/tspi/gtk/support.c @@ -0,0 +1,157 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004 + * + */ + +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <string.h> +#include <stdio.h> + +#include <gtk/gtk.h> + +#include "trousers/tss.h" +#include "tsplog.h" + +#include "support.h" + +GtkWidget* +lookup_widget (GtkWidget *widget, + const gchar *widget_name) +{ + GtkWidget *parent, *found_widget; + + for (;;) + { + if (GTK_IS_MENU (widget)) + parent = gtk_menu_get_attach_widget (GTK_MENU (widget)); + else + parent = widget->parent; + if (!parent) + parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey"); + if (parent == NULL) + break; + widget = parent; + } + + found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget), + widget_name); + if (!found_widget) + g_warning ("Widget not found: %s", widget_name); + return found_widget; +} + +static GList *pixmaps_directories = NULL; + +/* Use this function to set the directory containing installed pixmaps. */ +void +__tspi_add_pixmap_directory (const gchar *directory) +{ + pixmaps_directories = g_list_prepend (pixmaps_directories, + g_strdup (directory)); +} + +/* This is an internally used function to find pixmap files. */ +static gchar* +find_pixmap_file (const gchar *filename) +{ + GList *elem; + + /* We step through each of the pixmaps directory to find it. */ + elem = pixmaps_directories; + while (elem) + { + gchar *pathname = g_strdup_printf ("%s%s%s", (gchar*)elem->data, + G_DIR_SEPARATOR_S, filename); + if (g_file_test (pathname, G_FILE_TEST_EXISTS)) + return pathname; + g_free (pathname); + elem = elem->next; + } + return NULL; +} + +/* This is an internally used function to create pixmaps. */ +GtkWidget* +create_pixmap (GtkWidget *widget, + const gchar *filename) +{ + gchar *pathname = NULL; + GtkWidget *pixmap; + + if (!filename || !filename[0]) + return gtk_image_new (); + + pathname = find_pixmap_file (filename); + + if (!pathname) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return gtk_image_new (); + } + + pixmap = gtk_image_new_from_file (pathname); + g_free (pathname); + return pixmap; +} + +/* This is an internally used function to create pixmaps. */ +GdkPixbuf* +create_pixbuf (const gchar *filename) +{ + gchar *pathname = NULL; + GdkPixbuf *pixbuf; + GError *error = NULL; + + if (!filename || !filename[0]) + return NULL; + + pathname = find_pixmap_file (filename); + + if (!pathname) + { + g_warning (_("Couldn't find pixmap file: %s"), filename); + return NULL; + } + + pixbuf = gdk_pixbuf_new_from_file (pathname, &error); + if (!pixbuf) + { + LogError ("Failed to load pixbuf file: %s: %s\n", + pathname, error->message); + g_error_free (error); + } + g_free (pathname); + return pixbuf; +} + +/* This is used to set ATK action descriptions. */ +void +glade_set_atk_action_description (AtkAction *action, + const gchar *action_name, + const gchar *description) +{ + gint n_actions, i; + + n_actions = atk_action_get_n_actions (action); + for (i = 0; i < n_actions; i++) + { + if (!strcmp (atk_action_get_name (action, i), action_name)) + atk_action_set_description (action, i, description); + } +} + diff --git a/src/tspi/gtk/support.h b/src/tspi/gtk/support.h new file mode 100644 index 0000000..3b8186a --- /dev/null +++ b/src/tspi/gtk/support.h @@ -0,0 +1,81 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004 + * + */ + +#ifndef _SUPPORT_H_ +#define _SUPPOR_H_ + +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <gtk/gtk.h> + +/* + * Standard gettext macros. + */ +#ifdef ENABLE_NLS +# include <libintl.h> +# undef _ +# define _(String) dgettext (PACKAGE, String) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +# define textdomain(String) (String) +# define gettext(String) (String) +# define dgettext(Domain,Message) (Message) +# define dcgettext(Domain,Message,Type) (Message) +# define bindtextdomain(Domain,Directory) (Domain) +# define _(String) (String) +# define N_(String) (String) +#endif + + +/* + * Public Functions. + */ + +/* + * This function returns a widget in a component created by Glade. + * Call it with the toplevel widget in the component (i.e. a window/dialog), + * or alternatively any widget in the component, and the name of the widget + * you want returned. + */ +GtkWidget* lookup_widget (GtkWidget *widget, + const gchar *widget_name); + + +/* Use this function to set the directory containing installed pixmaps. */ +void __tspi_add_pixmap_directory (const gchar *directory); + + +/* + * Private Functions. + */ + +/* This is used to create the pixmaps used in the interface. */ +GtkWidget* create_pixmap (GtkWidget *widget, + const gchar *filename); + +/* This is used to create the pixbufs used in the interface. */ +GdkPixbuf* create_pixbuf (const gchar *filename); + +/* This is used to set ATK action descriptions. */ +void glade_set_atk_action_description (AtkAction *action, + const gchar *action_name, + const gchar *description); + +#endif diff --git a/src/tspi/log.c b/src/tspi/log.c new file mode 100644 index 0000000..9f691be --- /dev/null +++ b/src/tspi/log.c @@ -0,0 +1,62 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004, 2005 + * + */ + + +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "tsplog.h" + +#ifdef TSS_DEBUG + +/* + * LogBlobData() + * + * Log a blob's data to the debugging stream + * + * szDescriptor - The APPID tag found in the caller's environment at build time + * sizeOfBlob - The size of the data to log + * blob - the data to log + * + */ + + +void +LogBlobData(char *szDescriptor, unsigned long sizeOfBlob, unsigned char *blob) +{ + char temp[64]; + int i; + + if (getenv("TSS_DEBUG_OFF")) + return; + + memset(temp, 0, sizeof(temp)); + + for (i = 0; (unsigned long)i < sizeOfBlob; i++) { + if ((i > 0) && ((i % 16) == 0)) { + fprintf(stdout, "%s\n", temp); + memset(temp, 0, sizeof(temp)); + } + snprintf(&temp[(i%16)*3], 4, "%.2X ", blob[i]); + } + fprintf(stdout, "%s\n", temp); +} + +TSS_RESULT +LogTSPERR(TSS_RESULT result, char *file, int line) +{ + if (getenv("TSS_DEBUG_OFF") == NULL) + fprintf(stderr, "%s %s %s:%d: 0x%x\n", "LOG_RETERR", APPID, file, line, result); + + return (result | TSS_LAYER_TSP); +} + +#endif diff --git a/src/tspi/obj.c b/src/tspi/obj.c new file mode 100644 index 0000000..ad5c79a --- /dev/null +++ b/src/tspi/obj.c @@ -0,0 +1,297 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "tsplog.h" +#include "obj.h" + +UINT32 nextObjectHandle = 0xC0000000; + +MUTEX_DECLARE_INIT(handle_lock); + +TPM_LIST_DECLARE; +CONTEXT_LIST_DECLARE; +HASH_LIST_DECLARE; +PCRS_LIST_DECLARE; +POLICY_LIST_DECLARE; +RSAKEY_LIST_DECLARE; +ENCDATA_LIST_DECLARE; +DAACRED_LIST_DECLARE; +DAAARAKEY_LIST_DECLARE; +DAAISSUERKEY_LIST_DECLARE; +NVSTORE_LIST_DECLARE; +DELFAMILY_LIST_DECLARE; +MIGDATA_LIST_DECLARE; + +void +list_init(struct obj_list *list) +{ + list->head = NULL; + MUTEX_INIT(list->lock); +} + +void +__tspi_obj_list_init() +{ + TPM_LIST_INIT(); + CONTEXT_LIST_INIT(); + HASH_LIST_INIT(); + PCRS_LIST_INIT(); + POLICY_LIST_INIT(); + RSAKEY_LIST_INIT(); + ENCDATA_LIST_INIT(); + DAACRED_LIST_INIT(); + DAAARAKEY_LIST_INIT(); + DAAISSUERKEY_LIST_INIT(); + NVSTORE_LIST_INIT(); + DELFAMILY_LIST_INIT(); + MIGDATA_LIST_INIT(); +} + +TSS_HOBJECT +obj_get_next_handle() +{ + MUTEX_LOCK(handle_lock); + + /* return any object handle except NULL_HOBJECT */ + do { + nextObjectHandle++; + } while (nextObjectHandle == NULL_HOBJECT); + + MUTEX_UNLOCK(handle_lock); + + return nextObjectHandle; +} + +/* search through the provided list for an object with handle matching + * @handle. If found, return a pointer to the object with the list + * locked, else return NULL. To release the lock, caller should + * call obj_list_put() after manipulating the object. + */ +struct tsp_object * +obj_list_get_obj(struct obj_list *list, UINT32 handle) +{ + struct tsp_object *obj; + + MUTEX_LOCK(list->lock); + + for (obj = list->head; obj; obj = obj->next) { + if (obj->handle == handle) + break; + } + + if (obj == NULL) + MUTEX_UNLOCK(list->lock); + + return obj; +} + +/* search through the provided list for an object with TSP context + * matching @tspContext. If found, return a pointer to the object + * with the list locked, else return NULL. To release the lock, + * caller should call obj_list_put() after manipulating the object. + */ +struct tsp_object * +obj_list_get_tspcontext(struct obj_list *list, UINT32 tspContext) +{ + struct tsp_object *obj; + + MUTEX_LOCK(list->lock); + + for (obj = list->head; obj; obj = obj->next) { + if (obj->tspContext == tspContext) + break; + } + + return obj; +} + +/* release a list whose handle was returned by obj_list_get_obj() */ +void +obj_list_put(struct obj_list *list) +{ + MUTEX_UNLOCK(list->lock); +} + +TSS_RESULT +obj_list_add(struct obj_list *list, UINT32 tsp_context, TSS_FLAG flags, void *data, + TSS_HOBJECT *phObject) +{ + struct tsp_object *new_obj, *tmp; + + new_obj = calloc(1, sizeof(struct tsp_object)); + if (new_obj == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(struct tsp_object)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + new_obj->handle = obj_get_next_handle(); + new_obj->flags = flags; + new_obj->data = data; + + if (list == &context_list) + new_obj->tspContext = new_obj->handle; + else + new_obj->tspContext = tsp_context; + + MUTEX_LOCK(list->lock); + + if (list->head == NULL) { + list->head = new_obj; + } else { + tmp = list->head; + list->head = new_obj; + new_obj->next = tmp; + } + + MUTEX_UNLOCK(list->lock); + + *phObject = new_obj->handle; + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_list_remove(struct obj_list *list, void (*freeFcn)(void *), TSS_HOBJECT hObject, TSS_HCONTEXT tspContext) +{ + struct tsp_object *obj, *prev = NULL; + + MUTEX_LOCK(list->lock); + + for (obj = list->head; obj; prev = obj, obj = obj->next) { + if (obj->handle == hObject) { + /* validate tspContext */ + if (obj->tspContext != tspContext) + break; + + (*freeFcn)(obj->data); + + if (prev) + prev->next = obj->next; + else + list->head = obj->next; + free(obj); + + MUTEX_UNLOCK(list->lock); + return TSS_SUCCESS; + } + } + + MUTEX_UNLOCK(list->lock); + + return TSPERR(TSS_E_INVALID_HANDLE); +} + +/* a generic routine for removing all members of a list who's tsp context + * matches @tspContext */ +void +obj_list_close(struct obj_list *list, void (*freeFcn)(void *), TSS_HCONTEXT tspContext) +{ + struct tsp_object *index; + struct tsp_object *next = NULL; + struct tsp_object *toKill; + struct tsp_object *prev = NULL; + + MUTEX_LOCK(list->lock); + + for (index = list->head; index; ) { + next = index->next; + if (index->tspContext == tspContext) { + toKill = index; + if (prev == NULL) { + list->head = toKill->next; + } else { + prev->next = toKill->next; + } + + (*freeFcn)(toKill->data); + free(toKill); + + index = next; + } else { + prev = index; + index = next; + } + } + + MUTEX_UNLOCK(list->lock); +} + +void +obj_close_context(TSS_HCONTEXT tspContext) +{ + TPM_LIST_CLOSE(tspContext); + CONTEXT_LIST_CLOSE(tspContext); + HASH_LIST_CLOSE(tspContext); + PCRS_LIST_CLOSE(tspContext); + POLICY_LIST_CLOSE(tspContext); + RSAKEY_LIST_CLOSE(tspContext); + ENCDATA_LIST_CLOSE(tspContext); + DAACRED_LIST_CLOSE(tspContext); + DAAARAKEY_LIST_CLOSE(tspContext); + DAAISSUERKEY_LIST_CLOSE(tspContext); + NVSTORE_LIST_CLOSE(tspContext); + DELFAMILY_LIST_CLOSE(tspContext); + MIGDATA_LIST_CLOSE(tspContext); +} + +/* When a policy object is closed, all references to it must be removed. This function + * calls the object specific routines for each working object type to remove all refs to the + * policy */ +void +obj_lists_remove_policy_refs(TSS_HPOLICY hPolicy, TSS_HCONTEXT tspContext) +{ + obj_rsakey_remove_policy_refs(hPolicy, tspContext); + obj_encdata_remove_policy_refs(hPolicy, tspContext); + obj_tpm_remove_policy_refs(hPolicy, tspContext); +} + +/* search all key lists (right now only RSA keys exist) looking for a TCS key handle, when + * found, return the hash of its TPM_STORE_PUBKEY structure */ +TSS_RESULT +obj_tcskey_get_pubkeyhash(TCS_KEY_HANDLE hKey, BYTE *pubKeyHash) +{ + struct tsp_object *obj; + struct obj_list *list = &rsakey_list; + struct tr_rsakey_obj *rsakey = NULL; + TSS_RESULT result = TSS_SUCCESS; + Trspi_HashCtx hashCtx; + + MUTEX_LOCK(list->lock); + + for (obj = list->head; obj; obj = obj->next) { + rsakey = (struct tr_rsakey_obj *)obj->data; + if (rsakey->tcsHandle == hKey) + break; + } + + if (obj == NULL || rsakey == NULL) { + MUTEX_UNLOCK(list->lock); + return TSPERR(TSS_E_KEY_NOT_LOADED); + } + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_STORE_PUBKEY(&hashCtx, &rsakey->key.pubKey); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash))) + result = TSPERR(TSS_E_INTERNAL_ERROR); + + MUTEX_UNLOCK(list->lock); + + return result; +} diff --git a/src/tspi/obj_context.c b/src/tspi/obj_context.c new file mode 100644 index 0000000..cb2091e --- /dev/null +++ b/src/tspi/obj_context.c @@ -0,0 +1,1524 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2005, 2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "tcs_tsp.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +obj_context_add(TSS_HOBJECT *phObject) +{ + TSS_RESULT result; + struct tr_context_obj *context = calloc(1, sizeof(struct tr_context_obj)); + unsigned len = strlen(TSS_LOCALHOST_STRING) + 1; + + if (context == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(struct tr_context_obj)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + +#ifndef TSS_NO_GUI + context->silentMode = TSS_TSPATTRIB_CONTEXT_NOT_SILENT; +#else + context->silentMode = TSS_TSPATTRIB_CONTEXT_SILENT; +#endif + if ((context->machineName = calloc(1, len)) == NULL) { + LogError("malloc of %u bytes failed", len); + free(context); + return TSPERR(TSS_E_OUTOFMEMORY); + } + memcpy(context->machineName, TSS_LOCALHOST_STRING, len); + context->machineNameLength = len; + + context->hashMode = TSS_TSPATTRIB_HASH_MODE_NOT_NULL; + context->connection_policy = TSS_TSPATTRIB_CONTEXT_VERSION_V1_1; + + if ((result = obj_list_add(&context_list, NULL_HCONTEXT, 0, context, phObject))) { + free(context->machineName); + free(context); + return result; + } + + /* Add the default policy */ + if ((result = obj_policy_add(*phObject, TSS_POLICY_USAGE, &context->policy))) { + obj_list_remove(&context_list, &__tspi_obj_context_free, *phObject, *phObject); + return result; + } + + context->tcs_api = &tcs_normal_api; + + return TSS_SUCCESS; +} + +struct tcs_api_table * +obj_context_get_tcs_api(TSS_HCONTEXT tspContext) +{ + struct tsp_object *obj; + struct tr_context_obj *context; + struct tcs_api_table *t; + + /* If the object cannot be found with the given handle, return a safe value, the normal TCS + * API pointer. Since the handle is bad, the RPC_ function will barf in looking up the + * corresponding TCS context handle and an invalid handle error will be returned. */ + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return &tcs_normal_api; + + context = (struct tr_context_obj *)obj->data; + + /* Return the current API set we're using, either the normal API, or the transport encrypted + * API. The context->tcs_api variable is switched back and forth between the two sets by + * the obj_context_transport_set_control function through a set attrib. */ + t = context->tcs_api; + + obj_list_put(&context_list); + + return t; +} + +void +__tspi_obj_context_free(void *data) +{ + struct tr_context_obj *context = (struct tr_context_obj *)data; + + free(context->machineName); + free(context); +} + +TSS_BOOL +obj_is_context(TSS_HOBJECT hObject) +{ + TSS_BOOL answer = FALSE; + + if ((obj_list_get_obj(&context_list, hObject))) { + answer = TRUE; + obj_list_put(&context_list); + } + + return answer; +} + +/* Clean up transport session if necessary. */ +void +obj_context_close(TSS_HCONTEXT tspContext) +{ + struct tsp_object *obj; + struct tr_context_obj *context; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return; + + context = (struct tr_context_obj *)obj->data; + +#ifdef TSS_BUILD_TRANSPORT + if (context->transAuth.AuthHandle) { + RPC_FlushSpecific(tspContext, context->transAuth.AuthHandle, TPM_RT_TRANS); + + memset(&context->transPub, 0, sizeof(TPM_TRANSPORT_PUBLIC)); + memset(&context->transMod, 0, sizeof(TPM_MODIFIER_INDICATOR)); + memset(&context->transSecret, 0, sizeof(TPM_TRANSPORT_AUTH)); + memset(&context->transAuth, 0, sizeof(TPM_AUTH)); + memset(&context->transLogIn, 0, sizeof(TPM_TRANSPORT_LOG_IN)); + memset(&context->transLogOut, 0, sizeof(TPM_TRANSPORT_LOG_OUT)); + memset(&context->transLogDigest, 0, sizeof(TPM_DIGEST)); + } +#endif + + obj_list_put(&context_list); +} + +TSS_RESULT +obj_context_get_policy(TSS_HCONTEXT tspContext, UINT32 policyType, TSS_HPOLICY *phPolicy) +{ + struct tsp_object *obj; + struct tr_context_obj *context; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + + switch (policyType) { + case TSS_POLICY_USAGE: + *phPolicy = context->policy; + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + obj_list_put(&context_list); + + return result; +} + +TSS_RESULT +obj_context_get_machine_name(TSS_HCONTEXT tspContext, UINT32 *size, BYTE **data) +{ + struct tsp_object *obj; + struct tr_context_obj *context; + TSS_RESULT result; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + + if (context->machineNameLength == 0) { + *data = NULL; + *size = 0; + } else { + /* + * Don't use calloc_tspi because this memory is + * not freed using "free_tspi" + */ + *data = calloc(1, context->machineNameLength); + if (*data == NULL) { + LogError("malloc of %u bytes failed.", + context->machineNameLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + *size = context->machineNameLength; + memcpy(*data, context->machineName, *size); + } + + result = TSS_SUCCESS; + +done: + obj_list_put(&context_list); + + return result; +} + +/* This function converts the machine name to a TSS_UNICODE string before + * returning it, as Tspi_GetAttribData would like. We could do the conversion + * in Tspi_GetAttribData, but we don't have access to the TSP context there */ +TSS_RESULT +obj_context_get_machine_name_attrib(TSS_HCONTEXT tspContext, UINT32 *size, BYTE **data) +{ + struct tsp_object *obj; + struct tr_context_obj *context; + BYTE *utf_string; + UINT32 utf_size; + TSS_RESULT result; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + + if (context->machineNameLength == 0) { + *data = NULL; + *size = 0; + } else { + utf_size = context->machineNameLength; + utf_string = Trspi_Native_To_UNICODE(context->machineName, + &utf_size); + if (utf_string == NULL) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *data = calloc_tspi(obj->tspContext, utf_size); + if (*data == NULL) { + free(utf_string); + LogError("malloc of %u bytes failed.", utf_size); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + *size = utf_size; + memcpy(*data, utf_string, utf_size); + free(utf_string); + } + + result = TSS_SUCCESS; + +done: + obj_list_put(&context_list); + + return result; +} + +TSS_RESULT +obj_context_set_machine_name(TSS_HCONTEXT tspContext, BYTE *name, UINT32 len) +{ + struct tsp_object *obj; + struct tr_context_obj *context; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + + free(context->machineName); + context->machineName = name; + context->machineNameLength = len; + + obj_list_put(&context_list); + + return TSS_SUCCESS; +} + +TSS_BOOL +obj_context_is_silent(TSS_HCONTEXT tspContext) +{ + struct tsp_object *obj; + struct tr_context_obj *context; + TSS_BOOL silent = FALSE; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return FALSE; + + context = (struct tr_context_obj *)obj->data; + if (context->silentMode == TSS_TSPATTRIB_CONTEXT_SILENT) + silent = TRUE; + + obj_list_put(&context_list); + + return silent; +} + +TSS_RESULT +obj_context_get_mode(TSS_HCONTEXT tspContext, UINT32 *mode) +{ + struct tsp_object *obj; + struct tr_context_obj *context; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + *mode = context->silentMode; + + obj_list_put(&context_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_context_set_mode(TSS_HCONTEXT tspContext, UINT32 mode) +{ + struct tsp_object *obj; + struct tr_context_obj *context; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + context->silentMode = mode; + + obj_list_put(&context_list); + + return TSS_SUCCESS; +} + +/* search the list of all policies bound to context @tspContext. If + * one is found of type popup, return TRUE, else return FALSE. */ +TSS_BOOL +obj_context_has_popups(TSS_HCONTEXT tspContext) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + struct obj_list *list = &policy_list; + TSS_BOOL ret = FALSE; + + MUTEX_LOCK(list->lock); + + for (obj = list->head; obj; obj = obj->next) { + if (obj->tspContext == tspContext) { + policy = (struct tr_policy_obj *)obj->data; + if (policy->SecretMode == TSS_SECRET_MODE_POPUP) + ret = TRUE; + break; + } + } + + MUTEX_UNLOCK(list->lock); + + return ret; +} + +TSS_RESULT +obj_context_get_hash_mode(TSS_HCONTEXT tspContext, UINT32 *mode) +{ + struct tsp_object *obj; + struct tr_context_obj *context; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + *mode = context->hashMode; + + obj_list_put(&context_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_context_set_hash_mode(TSS_HCONTEXT tspContext, UINT32 mode) +{ + struct tsp_object *obj; + struct tr_context_obj *context; + + switch (mode) { + case TSS_TSPATTRIB_HASH_MODE_NULL: + case TSS_TSPATTRIB_HASH_MODE_NOT_NULL: + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_DATA); + } + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + context->hashMode = mode; + + obj_list_put(&context_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_context_get_connection_version(TSS_HCONTEXT tspContext, UINT32 *version) +{ + struct tsp_object *obj; + struct tr_context_obj *context; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + + *version = context->current_connection; + + obj_list_put(&context_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_context_set_connection_policy(TSS_HCONTEXT tspContext, UINT32 policy) +{ + struct tsp_object *obj; + struct tr_context_obj *context; + + switch (policy) { + case TSS_TSPATTRIB_CONTEXT_VERSION_V1_1: + case TSS_TSPATTRIB_CONTEXT_VERSION_V1_2: + case TSS_TSPATTRIB_CONTEXT_VERSION_AUTO: + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_DATA); + } + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + + context->connection_policy = policy; + + obj_list_put(&context_list); + + return TSS_SUCCESS; +} + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +obj_context_set_transport_key(TSS_HCONTEXT tspContext, TSS_HKEY hKey) +{ + struct tsp_object *obj; + struct tr_context_obj *context; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + + context->transKey = hKey; + + obj_list_put(&context_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_context_transport_get_mode(TSS_HCONTEXT tspContext, UINT32 value, UINT32 *out) +{ + TSS_RESULT result = TSS_SUCCESS; + struct tsp_object *obj; + struct tr_context_obj *context; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + + switch (value) { + case TSS_TSPATTRIB_TRANSPORT_NO_DEFAULT_ENCRYPTION: + *out = context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_DEFAULT_ENCRYPT ? + FALSE : TRUE; + break; + case TSS_TSPATTRIB_TRANSPORT_DEFAULT_ENCRYPTION: + *out = context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_DEFAULT_ENCRYPT ? + TRUE : FALSE; + break; + case TSS_TSPATTRIB_TRANSPORT_AUTHENTIC_CHANNEL: + *out = context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_AUTHENTIC ? + TRUE : FALSE; + break; + case TSS_TSPATTRIB_TRANSPORT_EXCLUSIVE: + *out = context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_EXCLUSIVE ? + TRUE : FALSE; + break; + case TSS_TSPATTRIB_TRANSPORT_STATIC_AUTH: + *out = context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_STATIC_AUTH ? + TRUE : FALSE; + break; + default: + LogError("Invalid attribute subflag: 0x%x", value); + result = TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + break; + } + + obj_list_put(&context_list); + + return result; +} + +TSS_RESULT +obj_context_transport_get_control(TSS_HCONTEXT tspContext, UINT32 value, UINT32 *out) +{ + TSS_RESULT result = TSS_SUCCESS; + struct tsp_object *obj; + struct tr_context_obj *context; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + + switch (value) { + case TSS_TSPATTRIB_DISABLE_TRANSPORT: + *out = context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_ENABLED ? FALSE : TRUE; + break; + case TSS_TSPATTRIB_ENABLE_TRANSPORT: + *out = context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_ENABLED ? TRUE : FALSE; + break; + default: + LogError("Invalid attribute subflag: 0x%x", value); + result = TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + break; + } + + obj_list_put(&context_list); + + return result; +} + +TSS_RESULT +obj_context_transport_set_control(TSS_HCONTEXT tspContext, UINT32 value) +{ + TSS_RESULT result = TSS_SUCCESS; + struct tsp_object *obj; + struct tr_context_obj *context; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + + switch (value) { + case TSS_TSPATTRIB_ENABLE_TRANSPORT: + context->flags |= TSS_CONTEXT_FLAGS_TRANSPORT_ENABLED; + context->tcs_api = &tcs_transport_api; + break; + case TSS_TSPATTRIB_DISABLE_TRANSPORT: + context->flags &= ~TSS_CONTEXT_FLAGS_TRANSPORT_ENABLED; + context->tcs_api = &tcs_normal_api; + break; + default: + LogError("Invalid attribute subflag: 0x%x", value); + result = TSPERR(TSS_E_INTERNAL_ERROR); + break; + } + + obj_list_put(&context_list); + + return result; +} + +TSS_RESULT +obj_context_transport_set_mode(TSS_HCONTEXT tspContext, UINT32 value) +{ + TSS_RESULT result = TSS_SUCCESS; + struct tsp_object *obj; + struct tr_context_obj *context; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + + switch (value) { + case TSS_TSPATTRIB_TRANSPORT_NO_DEFAULT_ENCRYPTION: + context->flags &= ~TSS_CONTEXT_FLAGS_TRANSPORT_DEFAULT_ENCRYPT; + break; + case TSS_TSPATTRIB_TRANSPORT_DEFAULT_ENCRYPTION: + context->flags |= TSS_CONTEXT_FLAGS_TRANSPORT_DEFAULT_ENCRYPT; + break; + case TSS_TSPATTRIB_TRANSPORT_AUTHENTIC_CHANNEL: + context->flags |= TSS_CONTEXT_FLAGS_TRANSPORT_AUTHENTIC; + break; + case TSS_TSPATTRIB_TRANSPORT_EXCLUSIVE: + context->flags |= TSS_CONTEXT_FLAGS_TRANSPORT_EXCLUSIVE; + break; + case TSS_TSPATTRIB_TRANSPORT_STATIC_AUTH: + context->flags |= TSS_CONTEXT_FLAGS_TRANSPORT_STATIC_AUTH; + break; + default: + LogError("Invalid attribute subflag: 0x%x", value); + result = TSPERR(TSS_E_INTERNAL_ERROR); + break; + } + + obj_list_put(&context_list); + + return result; +} + +#if 0 +TSS_RESULT +get_trans_props(TSS_HCONTEXT tspContext, UINT32 *alg, UINT16 *enc) +{ + TSS_RESULT result; + UINT32 algs[] = { TPM_ALG_MGF1, TPM_ALG_AES128, 0 }, a = 0; + UINT16 encs[] = { TPM_ES_SYM_OFB, TPM_ES_SYM_CNT, TPM_ES_SYM_CBC_PKCS5PAD, 0 }, e = 0; + BYTE *respData; + UINT32 respLen, tcsSubCap32; + UINT16 tcsSubCap16; + + if (*alg) + goto check_es; + + for (a = 0; algs[a]; a++) { + tcsSubCap32 = endian32(algs[a]); + + if ((result = RPC_GetTPMCapability(tspContext, TPM_CAP_TRANS_ALG, sizeof(UINT32), + (BYTE *)&tcsSubCap32, &respLen, &respData))) + return result; + + if (*(TSS_BOOL *)respData == TRUE) { + free(respData); + break; + } + free(respData); + } + + if (!algs[a]) { + LogError("TPM reports no usable sym algorithms for transport session"); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + +check_es: + if (*enc || algs[a] == TPM_ALG_MGF1) + goto done; + + for (e = 0; encs[e]; e++) { + tcsSubCap16 = endian16(encs[e]); + + if ((result = RPC_GetTPMCapability(tspContext, TPM_CAP_TRANS_ES, sizeof(UINT16), + (BYTE *)&tcsSubCap16, &respLen, &respData))) + return result; + + if (*(TSS_BOOL *)respData == TRUE) { + free(respData); + break; + } + free(respData); + } + + if (!encs[e]) { + LogError("TPM reports no usable sym modes for transport session"); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + *alg = algs[a]; + *enc = encs[e]; +done: + return TSS_SUCCESS; +} +#endif + +/* called before each TCSP_ExecuteTransport call */ +TSS_RESULT +obj_context_transport_init(TSS_HCONTEXT tspContext) +{ + TSS_RESULT result = TSS_SUCCESS; + struct tsp_object *obj; + struct tr_context_obj *context; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + + /* return immediately if we're not in a transport session */ + if (!(context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_ENABLED)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + /* if the session is not yet established, setup and call EstablishTransport */ + if (!(context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_ESTABLISHED)) { + if ((result = obj_context_transport_establish(tspContext, context))) + goto done; + } + + context->flags |= TSS_CONTEXT_FLAGS_TRANSPORT_ESTABLISHED; + + result = TSS_SUCCESS; +done: + obj_list_put(&context_list); + + return result; +} + +TSS_RESULT +obj_context_transport_establish(TSS_HCONTEXT tspContext, struct tr_context_obj *context) +{ + TSS_RESULT result; + UINT32 tickLen, secretLen, transPubLen, exclusive = TSS_TCSATTRIB_TRANSPORT_DEFAULT; + BYTE *ticks, *secret; + UINT64 offset; + Trspi_HashCtx hashCtx; + TPM_DIGEST digest; + TSS_HPOLICY hTransKeyPolicy; + TPM_AUTH auth, *pAuth, *pTransAuth; + TCS_KEY_HANDLE tcsTransKey; + TSS_BOOL usesAuth = FALSE; + UINT32 encKeyLen; + BYTE encKey[256]; + BYTE transPubBlob[sizeof(TPM_TRANSPORT_PUBLIC)]; + BYTE transAuthBlob[sizeof(TPM_TRANSPORT_AUTH)]; + + + context->transPub.tag = TPM_TAG_TRANSPORT_PUBLIC; + context->transSecret.tag = TPM_TAG_TRANSPORT_AUTH; + + if ((result = get_local_random(tspContext, FALSE, TPM_SHA1_160_HASH_LEN, + (BYTE **)context->transSecret.authData.authdata))) + return result; + + if (context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_STATIC_AUTH) + context->transKey = TPM_KH_TRANSPORT; + + if (context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_AUTHENTIC) + context->transPub.transAttributes |= TPM_TRANSPORT_LOG; + + if (context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_EXCLUSIVE) { + context->transPub.transAttributes |= TPM_TRANSPORT_EXCLUSIVE; + exclusive = TSS_TCSATTRIB_TRANSPORT_EXCLUSIVE; + } + + /* XXX implement AES128+CTR (Winbond, Infineon), then AES256+CTR (Atmel) */ + context->transPub.algId = TPM_ALG_MGF1; + context->transPub.encScheme = TPM_ES_NONE; + + if (context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_DEFAULT_ENCRYPT) { + context->transPub.transAttributes |= TPM_TRANSPORT_ENCRYPT; + + if (context->transKey == TPM_KH_TRANSPORT) { + LogError("No transport key handle has been set yet. Use " + "Tspi_Context_SetTransEncryptionKey to set this handle"); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + } + + if (context->transKey == TPM_KH_TRANSPORT) { + secret = context->transSecret.authData.authdata; + secretLen = TPM_SHA1_160_HASH_LEN; + } else { + offset = 0; + Trspi_LoadBlob_TRANSPORT_AUTH(&offset, transAuthBlob, &context->transSecret); + secretLen = offset; + + /* encrypt the sym key with the wrapping RSA key */ + encKeyLen = sizeof(encKey); + if ((result = __tspi_rsa_encrypt(context->transKey, secretLen, transAuthBlob, &encKeyLen, + encKey))) + return result; + + secret = encKey; + secretLen = encKeyLen; + } + + offset = 0; + Trspi_LoadBlob_TRANSPORT_PUBLIC(&offset, transPubBlob, &context->transPub); + transPubLen = offset; + + if (context->transKey != TPM_KH_TRANSPORT) { + if ((result = obj_rsakey_get_tcs_handle(context->transKey, &tcsTransKey))) + return result; + + if ((result = obj_rsakey_get_policy(context->transKey, TSS_POLICY_USAGE, + &hTransKeyPolicy, &usesAuth))) + return result; + + if (!usesAuth) { + LogError("Key used to establish a transport session must use auth"); + return TSPERR(TSS_E_TSP_TRANS_AUTHREQUIRED); + } + } else + tcsTransKey = TPM_KH_TRANSPORT; + + /* If logging is on, do TPM commands spec rev106 step 8.a */ + memset(context->transLogDigest.digest, 0, sizeof(TPM_DIGEST)); + if (context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_AUTHENTIC) { + context->transLogIn.tag = TPM_TAG_TRANSPORT_LOG_IN; + + /* step 8.a, i */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_EstablishTransport); + result |= Trspi_HashUpdate(&hashCtx, transPubLen, transPubBlob); + result |= Trspi_Hash_UINT32(&hashCtx, secretLen); + result |= Trspi_HashUpdate(&hashCtx, secretLen, secret); + if ((result |= Trspi_HashFinal(&hashCtx, context->transLogIn.parameters.digest))) + return result; + + /* step 8.a, ii */ + memset(context->transLogIn.pubKeyHash.digest, 0, sizeof(TPM_DIGEST)); + + /* step 8.a, iii */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, context->transLogDigest.digest); + result |= Trspi_Hash_TRANSPORT_LOG_IN(&hashCtx, &context->transLogIn); + if ((result |= Trspi_HashFinal(&hashCtx, context->transLogDigest.digest))) + return result; + } + + if (usesAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_EstablishTransport); + result |= Trspi_HashUpdate(&hashCtx, (UINT32)offset, (BYTE *)transPubBlob); + result |= Trspi_Hash_UINT32(&hashCtx, secretLen); + result |= Trspi_HashUpdate(&hashCtx, secretLen, secret); + if ((result |= Trspi_HashFinal(&hashCtx, (BYTE *)&digest))) + return result; + + /* open OIAP session with continueAuthSession = TRUE */ + if ((result = secret_PerformAuth_OIAP(context->transKey, TPM_ORD_EstablishTransport, + hTransKeyPolicy, TRUE, &digest, &auth))) + return result; + + pAuth = &auth; + } else + pAuth = NULL; + + result = RPC_EstablishTransport(tspContext, exclusive, tcsTransKey, transPubLen, + transPubBlob, secretLen, secret, pAuth, &context->transMod, + &context->transAuth.AuthHandle, &tickLen, &ticks, + &context->transAuth.NonceEven); + if (result) { + LogError("Establish Transport command failed: %s", Trspi_Error_String(result)); + return result; + } + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_EstablishTransport); + result |= Trspi_Hash_UINT32(&hashCtx, context->transMod); + result |= Trspi_HashUpdate(&hashCtx, tickLen, ticks); + result |= Trspi_Hash_NONCE(&hashCtx, context->transAuth.NonceEven.nonce); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if (usesAuth) { + if ((result = obj_policy_validate_auth_oiap(hTransKeyPolicy, &digest, pAuth))) + return result; + } + + /* step 8.b iii */ + offset = 0; + Trspi_UnloadBlob_CURRENT_TICKS(&offset, ticks, &context->transLogOut.currentTicks); + free(ticks); + + /* If logging is on, do TPM commands spec rev106 step 8.b */ + if (context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_AUTHENTIC) { + context->transLogOut.tag = TPM_TAG_TRANSPORT_LOG_OUT; + + /* step 8.b i */ + memcpy(context->transLogOut.parameters.digest, digest.digest, sizeof(TPM_DIGEST)); + + /* step 8.b ii */ + context->transLogOut.locality = context->transMod; + + /* step 8.b iii was done above */ + /* step 8.b iv */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, context->transLogDigest.digest); + result |= Trspi_Hash_TRANSPORT_LOG_OUT(&hashCtx, &context->transLogOut); + if ((result |= Trspi_HashFinal(&hashCtx, context->transLogDigest.digest))) + return result; + } + + LogDebug("Transport session established successfully"); + + pTransAuth = &context->transAuth; + pTransAuth->fContinueAuthSession = TRUE; + if ((result = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE), + (BYTE **)pTransAuth->NonceOdd.nonce))) { + LogError("Failed creating random nonce"); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + return TSS_SUCCESS; +} + +TSS_RESULT +do_transport_decryption(TPM_TRANSPORT_PUBLIC *transPub, + TPM_AUTH *pTransAuth, + BYTE *secret, + UINT32 inLen, + BYTE *in, + UINT32 *outLen, + BYTE **out) +{ + TSS_RESULT result; + UINT32 i, decLen; + UINT32 seedLen, ivLen; + BYTE *dec; + BYTE seed[(2 * sizeof(TPM_NONCE)) + strlen("out") + TPM_SHA1_160_HASH_LEN]; + + /* allocate the most data anyone below might need */ + decLen = inLen;//((inLen / TSS_MAX_SYM_BLOCK_SIZE) + 1) * TSS_MAX_SYM_BLOCK_SIZE; + if ((dec = malloc(decLen)) == NULL) { + LogError("malloc of %u bytes failed", decLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + /* set the common 3 initial values of 'seed', which is used to generate either the IV or + * mask */ + memcpy(seed, pTransAuth->NonceEven.nonce, sizeof(TPM_NONCE)); + memcpy(&seed[sizeof(TPM_NONCE)], pTransAuth->NonceOdd.nonce, sizeof(TPM_NONCE)); + memcpy(&seed[2 * sizeof(TPM_NONCE)], "out", strlen("out")); + + switch (transPub->algId) { + case TPM_ALG_MGF1: + { + decLen = inLen; + seedLen = sizeof(seed); + + /* add the secret data to the seed for MGF1 */ + memcpy(&seed[2 * sizeof(TPM_NONCE) + strlen("out")], secret, TPM_SHA1_160_HASH_LEN); + + if ((result = Trspi_MGF1(TSS_HASH_SHA1, seedLen, seed, decLen, dec))) { + free(dec); + return result; + } + + for (i = 0; i < inLen; i++) + dec[i] ^= in[i]; + break; + } + case TPM_ALG_AES128: + { + BYTE iv[TSS_MAX_SYM_BLOCK_SIZE]; + + ivLen = TSS_MAX_SYM_BLOCK_SIZE; + seedLen = (2 * sizeof(TPM_NONCE)) + strlen("out"); + + if ((result = Trspi_MGF1(TSS_HASH_SHA1, seedLen, seed, ivLen, iv))) { + free(dec); + return result; + } + + /* use the secret data as the key for AES */ + if ((result = Trspi_SymEncrypt(transPub->algId, transPub->encScheme, secret, iv, in, + inLen, dec, &decLen))) { + free(dec); + return result; + } + + break; + } + default: + LogDebug("Unknown algorithm for encrypted transport session: 0x%x", + transPub->algId); + free(dec); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + *out = dec; + *outLen = decLen; + + return result; +} + +TSS_RESULT +do_transport_encryption(TPM_TRANSPORT_PUBLIC *transPub, + TPM_AUTH *pTransAuth, + BYTE *secret, + UINT32 inLen, + BYTE *in, + UINT32 *outLen, + BYTE **out) +{ + TSS_RESULT result; + UINT32 i, encLen; + UINT32 seedLen, ivLen; + BYTE *enc; + BYTE seed[(2 * sizeof(TPM_NONCE)) + strlen("in") + TPM_SHA1_160_HASH_LEN]; + + /* allocate the most data anyone below might need */ + encLen = ((inLen / TSS_MAX_SYM_BLOCK_SIZE) + 1) * TSS_MAX_SYM_BLOCK_SIZE; + if ((enc = malloc(encLen)) == NULL) { + LogError("malloc of %u bytes failed", encLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + /* set the common 3 initial values of 'seed', which is used to generate either the IV or + * mask */ + memcpy(seed, pTransAuth->NonceEven.nonce, sizeof(TPM_NONCE)); + memcpy(&seed[sizeof(TPM_NONCE)], pTransAuth->NonceOdd.nonce, sizeof(TPM_NONCE)); + memcpy(&seed[2 * sizeof(TPM_NONCE)], "in", strlen("in")); + + switch (transPub->algId) { + case TPM_ALG_MGF1: + { + encLen = inLen; + seedLen = sizeof(seed); + + /* add the secret data to the seed for MGF1 */ + memcpy(&seed[2 * sizeof(TPM_NONCE) + strlen("in")], secret, TPM_SHA1_160_HASH_LEN); + + if ((result = Trspi_MGF1(TSS_HASH_SHA1, seedLen, seed, encLen, enc))) { + free(enc); + return result; + } + + for (i = 0; i < inLen; i++) + enc[i] ^= in[i]; + break; + } + case TPM_ALG_AES128: + { + BYTE iv[TSS_MAX_SYM_BLOCK_SIZE]; + + ivLen = TSS_MAX_SYM_BLOCK_SIZE; + seedLen = (2 * sizeof(TPM_NONCE)) + strlen("in"); + + if ((result = Trspi_MGF1(TSS_HASH_SHA1, seedLen, seed, ivLen, iv))) { + free(enc); + return result; + } + + /* use the secret data as the key for AES */ + if ((result = Trspi_SymEncrypt(transPub->algId, transPub->encScheme, secret, iv, in, + inLen, enc, &encLen))) { + free(enc); + return result; + } + + break; + } + default: + LogDebug("Unknown algorithm for encrypted transport session: 0x%x", + transPub->algId); + free(enc); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + *out = enc; + *outLen = encLen; + + return result; +} + +TSS_RESULT +obj_context_transport_execute(TSS_HCONTEXT tspContext, + TPM_COMMAND_CODE ordinal, + UINT32 ulDataLen, + BYTE* rgbData, + TPM_DIGEST* pubKeyHash, + UINT32* handlesLen, + TCS_HANDLE** handles, + TPM_AUTH* pAuth1, + TPM_AUTH* pAuth2, + UINT32* outLen, + BYTE** out) +{ + TSS_RESULT result = TSS_SUCCESS; + struct tsp_object *obj; + struct tr_context_obj *context; + UINT32 encLen, ulWrappedDataLen = 0; + BYTE *pEnc = NULL, *rgbWrappedData = NULL; + TPM_RESULT tpmResult; + Trspi_HashCtx hashCtx; + TPM_DIGEST etDigest, wDigest; + TPM_AUTH *pTransAuth; + UINT64 currentTicks; + TSS_BOOL free_enc = FALSE; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + + pTransAuth = &context->transAuth; + + /* TPM Commands spec rev106 step 6 */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, ordinal); + + switch (ordinal) { + case TPM_ORD_OSAP: + case TPM_ORD_OIAP: + break; + default: + result |= Trspi_HashUpdate(&hashCtx, ulDataLen, rgbData); + break; + } + + if ((result |= Trspi_HashFinal(&hashCtx, wDigest.digest))) + goto done; + + if (context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_AUTHENTIC) { + /* TPM Commands spec rev106 step 10.b */ + memcpy(context->transLogIn.parameters.digest, wDigest.digest, sizeof(TPM_DIGEST)); + /* TPM Commands spec rev106 step 10.c, d or e, calculated by the caller */ + if (pubKeyHash) + memcpy(context->transLogIn.pubKeyHash.digest, pubKeyHash->digest, + sizeof(TPM_DIGEST)); + else + memset(context->transLogIn.pubKeyHash.digest, 0, sizeof(TPM_DIGEST)); + + /* TPM Commands spec rev106 step 10.f */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, context->transLogDigest.digest); + result |= Trspi_Hash_TRANSPORT_LOG_IN(&hashCtx, &context->transLogIn); + if ((result |= Trspi_HashFinal(&hashCtx, context->transLogDigest.digest))) + goto done; + } + + /* TPM Commands spec rev106 step 7.a */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ExecuteTransport); + result |= Trspi_Hash_UINT32(&hashCtx, ulDataLen + TSS_TPM_TXBLOB_HDR_LEN + + (*handlesLen * sizeof(UINT32)) + + (pAuth1 ? TPM_AUTH_RQU_SIZE : 0) + + (pAuth2 ? TPM_AUTH_RQU_SIZE : 0)); + result |= Trspi_HashUpdate(&hashCtx, TPM_SHA1_160_HASH_LEN, wDigest.digest); + if ((result |= Trspi_HashFinal(&hashCtx, etDigest.digest))) + goto done; + + /* encrypt the data if necessary */ + if (ulDataLen && context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_DEFAULT_ENCRYPT) { + switch (ordinal) { + case TPM_ORD_OSAP: + case TPM_ORD_OIAP: + encLen = ulDataLen; + pEnc = rgbData; + break; + case TPM_ORD_DSAP: + { + UINT64 offset; + UINT32 tmpLen, entityValueLen; + BYTE *tmpEnc, *entityValuePtr; + + /* DSAP is a special case where only entityValue is encrypted. So, we'll + * parse through rgbData until we get to entityValue, encrypt it, alloc + * new space for rgbData (since it could be up to a block length larger + * than it came in) and copy the unencrypted data and the encrypted + * entityValue to the new block, setting pEnc and encLen to new values. */ + + offset = (2 * sizeof(UINT32)) + sizeof(TPM_NONCE); + Trspi_UnloadBlob_UINT32(&offset, &entityValueLen, rgbData); + + entityValuePtr = &rgbData[offset]; + if ((result = do_transport_encryption(&context->transPub, pTransAuth, + context->transSecret.authData.authdata, + entityValueLen, entityValuePtr, &tmpLen, + &tmpEnc))) + goto done; + + /* offset is the amount of data before the block we encrypted and tmpLen is + * the size of the encrypted data */ + encLen = offset + tmpLen; + if ((pEnc = malloc(encLen)) == NULL) { + LogError("malloc of %u bytes failed.", encLen); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(pEnc, rgbData, offset); + memcpy(&pEnc[offset], tmpEnc, tmpLen); + free(tmpEnc); + + free_enc = TRUE; + break; + } + default: + if ((result = do_transport_encryption(&context->transPub, pTransAuth, + context->transSecret.authData.authdata, + ulDataLen, rgbData, &encLen, &pEnc))) + goto done; + + free_enc = TRUE; + break; + } + } else { + encLen = ulDataLen; + pEnc = rgbData; + } + + /* TPM Commands spec rev106 step 7.b */ + HMAC_Auth(context->transSecret.authData.authdata, etDigest.digest, pTransAuth); + + if ((result = RPC_ExecuteTransport(tspContext, ordinal, encLen, pEnc, handlesLen, handles, + pAuth1, pAuth2, pTransAuth, ¤tTicks, + &context->transMod, &tpmResult, &ulWrappedDataLen, + &rgbWrappedData))) { + LogDebugFn("Execute Transport failed: %s", Trspi_Error_String(result)); + goto done; + } + + if (tpmResult) { + LogDebug("Wrapped command ordinal 0x%x failed with result: 0x%x", ordinal, + tpmResult); + result = tpmResult; + goto done; + } + + /* decrypt the returned wrapped data if necessary */ + if (ulWrappedDataLen && context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_DEFAULT_ENCRYPT) { + switch (ordinal) { + case TPM_ORD_OSAP: + case TPM_ORD_OIAP: + case TPM_ORD_DSAP: + *outLen = ulWrappedDataLen; + *out = rgbWrappedData; + break; + default: + if ((result = do_transport_decryption(&context->transPub, pTransAuth, + context->transSecret.authData.authdata, + ulWrappedDataLen, rgbWrappedData, outLen, + out))) + goto done; + + free(rgbWrappedData); + } + } else { + if (outLen) { + *outLen = ulWrappedDataLen; + *out = rgbWrappedData; + } + } + + /* TPM Commands spec rev106 step 14 */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, tpmResult); + result |= Trspi_Hash_UINT32(&hashCtx, ordinal); + + switch (ordinal) { + case TPM_ORD_OSAP: + case TPM_ORD_OIAP: + break; + default: + if (outLen) + result |= Trspi_HashUpdate(&hashCtx, *outLen, *out); + break; + } + + if ((result |= Trspi_HashFinal(&hashCtx, wDigest.digest))) + goto done; + + /* TPM Commands spec rev106 step 15 */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ExecuteTransport); + result |= Trspi_Hash_UINT64(&hashCtx, currentTicks); + result |= Trspi_Hash_UINT32(&hashCtx, context->transMod); + result |= Trspi_Hash_UINT32(&hashCtx, (outLen ? *outLen : 0) + + TSS_TPM_TXBLOB_HDR_LEN + + (*handlesLen * sizeof(UINT32)) + + (pAuth1 ? TPM_AUTH_RSP_SIZE : 0) + + (pAuth2 ? TPM_AUTH_RSP_SIZE : 0)); + result |= Trspi_HashUpdate(&hashCtx, TPM_SHA1_160_HASH_LEN, wDigest.digest); + if ((result |= Trspi_HashFinal(&hashCtx, etDigest.digest))) + goto done; + + if (validateReturnAuth(context->transSecret.authData.authdata, etDigest.digest, + pTransAuth)) { + result = TSPERR(TSS_E_TSP_TRANS_AUTHFAIL); + goto done; + } + + if (context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_AUTHENTIC) { + context->transLogOut.currentTicks.currentTicks = currentTicks; + + /* TPM Commands spec rev106 step 16.b */ + memcpy(context->transLogOut.parameters.digest, wDigest.digest, sizeof(TPM_DIGEST)); + /* TPM Commands spec rev106 step 16.c done above */ + /* TPM Commands spec rev106 step 16.d */ + context->transLogOut.locality = context->transMod; + + /* TPM Commands spec rev106 step 16.d */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, context->transLogDigest.digest); + result |= Trspi_Hash_TRANSPORT_LOG_OUT(&hashCtx, &context->transLogOut); + if ((result |= Trspi_HashFinal(&hashCtx, context->transLogDigest.digest))) + goto done; + } + + /* Refresh nonceOdd for continued transport auth session */ + if ((result = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE), + (BYTE **)pTransAuth->NonceOdd.nonce))) { + LogError("Failed creating random nonce"); + } + +done: + if (free_enc) + free(pEnc); + obj_list_put(&context_list); + + return result; +} + +/* called to close a transport session */ +TSS_RESULT +obj_context_transport_close(TSS_HCONTEXT tspContext, + TSS_HKEY hKey, + TSS_HPOLICY hPolicy, + TSS_BOOL usesAuth, + TPM_SIGN_INFO* signInfo, + UINT32* sigLen, + BYTE** sig) +{ + TSS_RESULT result = TSS_SUCCESS; + struct tsp_object *obj; + struct tr_context_obj *context; + Trspi_HashCtx hashCtx; + TPM_DIGEST digest; + TPM_AUTH auth, *pAuth; + TCS_KEY_HANDLE tcsKey; + BYTE *ticks = NULL; + UINT32 tickLen; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + + /* return immediately if we're not in a transport session */ + if (!(context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_ENABLED)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKey))) + goto done; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ReleaseTransportSigned); + result |= Trspi_Hash_NONCE(&hashCtx, signInfo->replay.nonce); + if ((result |= Trspi_HashFinal(&hashCtx, (BYTE *)&digest))) + goto done; + + if (usesAuth) { + if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_ReleaseTransportSigned, + hPolicy, FALSE, &digest, &auth))) + goto done; + + pAuth = &auth; + } else + pAuth = NULL; + + /* continue the auth session established in obj_context_transport_establish */ + HMAC_Auth(context->transSecret.authData.authdata, digest.digest, &context->transAuth); + + if ((result = RPC_ReleaseTransportSigned(tspContext, tcsKey, &signInfo->replay, pAuth, + &context->transAuth, + &context->transLogOut.locality, &tickLen, &ticks, + sigLen, sig))) + goto done; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ReleaseTransportSigned); + result |= Trspi_Hash_UINT32(&hashCtx, context->transLogOut.locality); + result |= Trspi_HashUpdate(&hashCtx, tickLen, ticks); + result |= Trspi_Hash_UINT32(&hashCtx, *sigLen); + result |= Trspi_HashUpdate(&hashCtx, *sigLen, *sig); + if ((result |= Trspi_HashFinal(&hashCtx, (BYTE *)&digest))) + goto done_disabled; + + /* validate the return data using the key's auth */ + if (pAuth) { + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth))) + goto done_disabled; + } + + /* validate again using the transport session's auth */ + if ((result = validateReturnAuth(context->transSecret.authData.authdata, digest.digest, + &context->transAuth))) { + result = TSPERR(TSS_E_TSP_TRANS_AUTHFAIL); + goto done_disabled; + } + + if (context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_AUTHENTIC) { + UINT64 offset; + + /* TPM Commands Spec step 6.b */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ReleaseTransportSigned); + result |= Trspi_Hash_NONCE(&hashCtx, signInfo->replay.nonce); + if ((result |= Trspi_HashFinal(&hashCtx, context->transLogOut.parameters.digest))) + goto done_disabled; + + /* TPM Commands Spec step 6.c */ + offset = 0; + Trspi_UnloadBlob_CURRENT_TICKS(&offset, ticks, &context->transLogOut.currentTicks); + free(ticks); + + /* TPM Commands Spec step 6.d was set above */ + /* TPM Commands Spec step 6.e */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, context->transLogDigest.digest); + result |= Trspi_Hash_TRANSPORT_LOG_OUT(&hashCtx, &context->transLogOut); + if ((result |= Trspi_HashFinal(&hashCtx, context->transLogDigest.digest))) + goto done_disabled; + } + + if ((signInfo->data = malloc(sizeof(TPM_DIGEST))) == NULL) { + LogError("malloc %zd bytes failed.", sizeof(TPM_DIGEST)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done_disabled; + } + memcpy(signInfo->data, context->transLogDigest.digest, sizeof(TPM_DIGEST)); + signInfo->dataLen = sizeof(TPM_DIGEST); + + /* destroy all transport session info, except the key handle */ + memset(&context->transPub, 0, sizeof(TPM_TRANSPORT_PUBLIC)); + memset(&context->transMod, 0, sizeof(TPM_MODIFIER_INDICATOR)); + memset(&context->transSecret, 0, sizeof(TPM_TRANSPORT_AUTH)); + memset(&context->transAuth, 0, sizeof(TPM_AUTH)); + memset(&context->transLogIn, 0, sizeof(TPM_TRANSPORT_LOG_IN)); + memset(&context->transLogOut, 0, sizeof(TPM_TRANSPORT_LOG_OUT)); + memset(&context->transLogDigest, 0, sizeof(TPM_DIGEST)); + +done_disabled: + context->flags &= ~TSS_CONTEXT_FLAGS_TRANSPORT_ESTABLISHED; +done: + obj_list_put(&context_list); + + return result; +} +#endif + +/* XXX change 0,1,2 to #defines */ +TSS_RESULT +obj_context_set_tpm_version(TSS_HCONTEXT tspContext, UINT32 ver) +{ + TSS_RESULT result = TSS_SUCCESS; + struct tsp_object *obj; + struct tr_context_obj *context; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + + switch (ver) { + case 1: + context->flags &= ~TSS_CONTEXT_FLAGS_TPM_VERSION_MASK; + context->flags |= TSS_CONTEXT_FLAGS_TPM_VERSION_1; + break; + case 2: + context->flags &= ~TSS_CONTEXT_FLAGS_TPM_VERSION_MASK; + context->flags |= TSS_CONTEXT_FLAGS_TPM_VERSION_2; + break; + default: + LogError("Invalid TPM version set: %u", ver); + result = TSPERR(TSS_E_INTERNAL_ERROR); + break; + } + + obj_list_put(&context_list); + + return result; +} + +/* XXX change 0,1,2 to #defines */ +TSS_RESULT +obj_context_get_tpm_version(TSS_HCONTEXT tspContext, UINT32 *ver) +{ + struct tsp_object *obj; + struct tr_context_obj *context; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + + if (context->flags & TSS_CONTEXT_FLAGS_TPM_VERSION_1) + *ver = 1; + else if (context->flags & TSS_CONTEXT_FLAGS_TPM_VERSION_2) + *ver = 2; + else + *ver = 0; + + obj_list_put(&context_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_context_get_loadkey_ordinal(TSS_HCONTEXT tspContext, TPM_COMMAND_CODE *ordinal) +{ + struct tsp_object *obj; + struct tr_context_obj *context; + + if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + context = (struct tr_context_obj *)obj->data; + + switch (context->flags & TSS_CONTEXT_FLAGS_TPM_VERSION_MASK) { + case TSS_CONTEXT_FLAGS_TPM_VERSION_2: + *ordinal = TPM_ORD_LoadKey2; + break; + default: + LogDebugFn("No TPM version set!"); + /* fall through */ + case TSS_CONTEXT_FLAGS_TPM_VERSION_1: + *ordinal = TPM_ORD_LoadKey; + break; + } + + obj_list_put(&context_list); + + return TSS_SUCCESS; +} + diff --git a/src/tspi/obj_daa.c b/src/tspi/obj_daa.c new file mode 100644 index 0000000..a073633 --- /dev/null +++ b/src/tspi/obj_daa.c @@ -0,0 +1,151 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006, 2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + +/* + * adds a new daa object to the daa list with TSP context tspContext + */ +TSS_RESULT +obj_daa_add(TSS_HCONTEXT tspContext, TSS_HOBJECT *phObject) +{ + TSS_RESULT result; + struct tr_daa_obj *daa = calloc(1, sizeof(struct tr_daa_obj)); + + if (daa == NULL) { + LogError("malloc of %d bytes failed.", sizeof(struct tr_daa_obj)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + if ((result = obj_list_add(&daa_list, tspContext, 0, daa, phObject))) { + free(daa); + return result; + } + + return TSS_SUCCESS; +} + +void +daa_free(void *data) +{ + struct tr_daa_obj *daa = (struct tr_daa_obj *)data; + + /* free all pointers in the tr_daa_obj object here */ + free(daa); +} + +/* + * remove DAA object hObject from the DAA list + */ +TSS_RESULT +obj_daa_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext) +{ + TSS_RESULT result; + + if ((result = obj_list_remove(&daa_list, &daa_free, hObject, tspContext))) + return result; + + return TSS_SUCCESS; +} + +TSS_BOOL +obj_is_daa(TSS_HOBJECT hObject) +{ + TSS_BOOL answer = FALSE; + + if ((obj_list_get_obj(&daa_list, hObject))) { + answer = TRUE; + obj_list_put(&daa_list); + } + + return answer; +} + +TSS_RESULT +obj_daa_get_tsp_context(TSS_HDAA hDaa, TSS_HCONTEXT *tspContext) +{ + struct tsp_object *obj; + + if ((obj = obj_list_get_obj(&daa_list, hDaa)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + *tspContext = obj->tspContext; + + obj_list_put(&daa_list); + + return TSS_SUCCESS; +} + +static TSS_RESULT +obj_daa_get_and_lock_data(TSS_HDAA hDaa, struct tr_daa_obj **daa) +{ + struct tsp_object *obj; + + if ((obj = obj_list_get_obj(&daa_list, hDaa)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + *daa = obj->data; + return TSS_SUCCESS; +} + +TSS_RESULT +obj_daa_get_handle_tpm(TSS_HDAA hDAA, TPM_HANDLE *hTPM) { + struct tr_daa_obj *daa_struct; + TSS_RESULT result; + + if( (result = obj_daa_get_and_lock_data( hDAA, &daa_struct)) != TSS_SUCCESS) return result; + *hTPM = daa_struct->tpm_handle; + obj_list_put(&daa_list); + return TSS_SUCCESS; +} + +TSS_RESULT +obj_daa_set_handle_tpm(TSS_HDAA hDAA, TPM_HANDLE hTPM) { + struct tr_daa_obj *daa_struct; + TSS_RESULT result; + + if( (result = obj_daa_get_and_lock_data( hDAA, &daa_struct)) != TSS_SUCCESS) return result; + daa_struct->tpm_handle = hTPM; + obj_list_put(&daa_list); + return TSS_SUCCESS; +} + +TSS_RESULT +obj_daa_get_session_handle(TSS_HDAA hDAA, UINT32 *session_handle) { + struct tr_daa_obj *daa_struct; + TSS_RESULT result; + + if( (result = obj_daa_get_and_lock_data( hDAA, &daa_struct)) != TSS_SUCCESS) return result; + *session_handle = daa_struct->session_handle; + obj_list_put(&daa_list); + return TSS_SUCCESS; +} + +TSS_RESULT +obj_daa_set_session_handle(TSS_HDAA hDAA, UINT32 session_handle) { + struct tr_daa_obj *daa_struct; + TSS_RESULT result; + + if( (result = obj_daa_get_and_lock_data( hDAA, &daa_struct)) != TSS_SUCCESS) return result; + daa_struct->session_handle = session_handle; + obj_list_put(&daa_list); + return TSS_SUCCESS; +} diff --git a/src/tspi/obj_delfamily.c b/src/tspi/obj_delfamily.c new file mode 100644 index 0000000..340bd59 --- /dev/null +++ b/src/tspi/obj_delfamily.c @@ -0,0 +1,361 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" +#include "tsp_delegate.h" + +void +delfamily_free(void *data) +{ + struct tr_delfamily_obj *delfamily = (struct tr_delfamily_obj *)data; + + free(delfamily); +} + +TSS_BOOL +obj_is_delfamily(TSS_HOBJECT hObject) +{ + TSS_BOOL answer = FALSE; + + if ((obj_list_get_obj(&delfamily_list, hObject))) { + answer = TRUE; + obj_list_put(&delfamily_list); + } + + return answer; +} + +TSS_RESULT +obj_delfamily_add(TSS_HCONTEXT hContext, TSS_HOBJECT *phObject) +{ + TSS_RESULT result; + struct tr_delfamily_obj *delfamily = calloc(1, sizeof(struct tr_delfamily_obj)); + + if (delfamily == NULL) { + LogError("malloc of %zd bytes failed.", + sizeof(struct tr_delfamily_obj)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + if ((result = obj_list_add(&delfamily_list, hContext, 0, delfamily, phObject))) { + free(delfamily); + return result; + } + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_delfamily_remove(TSS_HDELFAMILY hFamily, TSS_HOBJECT hObject) +{ + TSS_HCONTEXT hContext; + TSS_RESULT result; + + if (obj_is_tpm(hObject)) { + if ((result = obj_tpm_get_tsp_context((TSS_HTPM)hObject, &hContext))) + return result; + } else + hContext = (TSS_HCONTEXT)hObject; + + if ((result = obj_list_remove(&delfamily_list, &delfamily_free, hFamily, hContext))) + return result; + + return TSS_SUCCESS; +} + +void +obj_delfamily_find_by_familyid(TSS_HOBJECT hObject, UINT32 familyID, TSS_HDELFAMILY *hFamily) +{ + TSS_HCONTEXT hContext; + struct tsp_object *obj; + struct obj_list *list = &delfamily_list; + struct tr_delfamily_obj *delfamily; + + pthread_mutex_lock(&list->lock); + + *hFamily = NULL_HDELFAMILY; + + if (obj_is_tpm(hObject)) { + if (obj_tpm_get_tsp_context((TSS_HTPM)hObject, &hContext)) + return; + } else + hContext = (TSS_HCONTEXT)hObject; + + for (obj = list->head; obj; obj = obj->next) { + if (obj->tspContext != hContext) + continue; + + delfamily = (struct tr_delfamily_obj *)obj->data; + if (delfamily->familyID == familyID) { + *hFamily = obj->handle; + break; + } + } + + pthread_mutex_unlock(&list->lock); +} + +TSS_RESULT +obj_delfamily_get_tsp_context(TSS_HDELFAMILY hFamily, TSS_HCONTEXT *hContext) +{ + struct tsp_object *obj; + + if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + *hContext = obj->tspContext; + + obj_list_put(&delfamily_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_delfamily_set_locked(TSS_HDELFAMILY hFamily, TSS_BOOL state, TSS_BOOL setInTpm) +{ + struct tsp_object *obj; + struct tr_delfamily_obj *delfamily; + TSS_HTPM hTpm; + UINT32 opDataSize; + BYTE opData[8]; + UINT32 outDataSize; + BYTE *outData = NULL; + UINT64 offset; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + delfamily = (struct tr_delfamily_obj *)obj->data; + + if (setInTpm) { + if ((result = obj_tpm_get(obj->tspContext, &hTpm))) + goto done; + + offset = 0; + Trspi_LoadBlob_BOOL(&offset, state, opData); + opDataSize = offset; + if ((result = do_delegate_manage(hTpm, delfamily->familyID, TPM_FAMILY_ADMIN, + opDataSize, opData, &outDataSize, &outData))) + goto done; + } + + if (state) + delfamily->stateFlags |= TSS_DELFAMILY_FLAGS_STATE_LOCKED; + else + delfamily->stateFlags &= ~TSS_DELFAMILY_FLAGS_STATE_LOCKED; + +done: + obj_list_put(&delfamily_list); + + free(outData); + + return result; +} + +TSS_RESULT +obj_delfamily_get_locked(TSS_HDELFAMILY hFamily, TSS_BOOL *state) +{ + struct tsp_object *obj; + struct tr_delfamily_obj *delfamily; + + if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + delfamily = (struct tr_delfamily_obj *)obj->data; + + *state = (delfamily->stateFlags & TSS_DELFAMILY_FLAGS_STATE_LOCKED) ? TRUE : FALSE; + + obj_list_put(&delfamily_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_delfamily_set_enabled(TSS_HDELFAMILY hFamily, TSS_BOOL state, TSS_BOOL setInTpm) +{ + struct tsp_object *obj; + struct tr_delfamily_obj *delfamily; + TSS_HTPM hTpm; + UINT32 opDataSize; + BYTE opData[8]; + UINT32 outDataSize; + BYTE *outData = NULL; + UINT64 offset; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + delfamily = (struct tr_delfamily_obj *)obj->data; + + if (setInTpm) { + if ((result = obj_tpm_get(obj->tspContext, &hTpm))) + goto done; + + offset = 0; + Trspi_LoadBlob_BOOL(&offset, state, opData); + opDataSize = offset; + if ((result = do_delegate_manage(hTpm, delfamily->familyID, TPM_FAMILY_ENABLE, + opDataSize, opData, &outDataSize, &outData))) + goto done; + } + + if (state) + delfamily->stateFlags |= TSS_DELFAMILY_FLAGS_STATE_ENABLED; + else + delfamily->stateFlags &= ~TSS_DELFAMILY_FLAGS_STATE_ENABLED; + +done: + obj_list_put(&delfamily_list); + + free(outData); + + return result; +} + +TSS_RESULT +obj_delfamily_get_enabled(TSS_HDELFAMILY hFamily, TSS_BOOL *state) +{ + struct tsp_object *obj; + struct tr_delfamily_obj *delfamily; + + if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + delfamily = (struct tr_delfamily_obj *)obj->data; + + *state = (delfamily->stateFlags & TSS_DELFAMILY_FLAGS_STATE_ENABLED) ? TRUE : FALSE; + + obj_list_put(&delfamily_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_delfamily_set_vercount(TSS_HDELFAMILY hFamily, UINT32 verCount) +{ + struct tsp_object *obj; + struct tr_delfamily_obj *delfamily; + + if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + delfamily = (struct tr_delfamily_obj *)obj->data; + + delfamily->verCount = verCount; + + obj_list_put(&delfamily_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_delfamily_get_vercount(TSS_HDELFAMILY hFamily, UINT32 *verCount) +{ + struct tsp_object *obj; + struct tr_delfamily_obj *delfamily; + + if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + delfamily = (struct tr_delfamily_obj *)obj->data; + + *verCount = delfamily->verCount; + + obj_list_put(&delfamily_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_delfamily_set_familyid(TSS_HDELFAMILY hFamily, UINT32 familyID) +{ + struct tsp_object *obj; + struct tr_delfamily_obj *delfamily; + + if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + delfamily = (struct tr_delfamily_obj *)obj->data; + + delfamily->familyID = familyID; + + obj_list_put(&delfamily_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_delfamily_get_familyid(TSS_HDELFAMILY hFamily, UINT32 *familyID) +{ + struct tsp_object *obj; + struct tr_delfamily_obj *delfamily; + + if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + delfamily = (struct tr_delfamily_obj *)obj->data; + + *familyID = delfamily->familyID; + + obj_list_put(&delfamily_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_delfamily_set_label(TSS_HDELFAMILY hFamily, BYTE label) +{ + struct tsp_object *obj; + struct tr_delfamily_obj *delfamily; + + if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + delfamily = (struct tr_delfamily_obj *)obj->data; + + delfamily->label = label; + + obj_list_put(&delfamily_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_delfamily_get_label(TSS_HDELFAMILY hFamily, BYTE *label) +{ + struct tsp_object *obj; + struct tr_delfamily_obj *delfamily; + + if ((obj = obj_list_get_obj(&delfamily_list, hFamily)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + delfamily = (struct tr_delfamily_obj *)obj->data; + + *label = delfamily->label; + + obj_list_put(&delfamily_list); + + return TSS_SUCCESS; +} + diff --git a/src/tspi/obj_encdata.c b/src/tspi/obj_encdata.c new file mode 100644 index 0000000..0931bcb --- /dev/null +++ b/src/tspi/obj_encdata.c @@ -0,0 +1,485 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2005, 2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + +TSS_RESULT +obj_encdata_add(TSS_HCONTEXT tspContext, UINT32 type, TSS_HOBJECT *phObject) +{ + TSS_RESULT result; + struct tr_encdata_obj *encdata = calloc(1, sizeof(struct tr_encdata_obj)); + + if (encdata == NULL) { + LogError("malloc of %zd bytes failed.", + sizeof(struct tr_encdata_obj)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + /* add usage policy */ + if ((result = obj_context_get_policy(tspContext, TSS_POLICY_USAGE, + &encdata->usagePolicy))) { + free(encdata); + return result; + } + + encdata->type = type; + + if ((result = obj_list_add(&encdata_list, tspContext, 0, encdata, phObject))) { + free(encdata); + return result; + } + + return TSS_SUCCESS; +} + +TSS_BOOL +obj_is_encdata(TSS_HOBJECT hObject) +{ + TSS_BOOL answer = FALSE; + + if ((obj_list_get_obj(&encdata_list, hObject))) { + answer = TRUE; + obj_list_put(&encdata_list); + } + + return answer; +} + +TSS_RESULT +obj_encdata_get_tsp_context(TSS_HENCDATA hEncdata, TSS_HCONTEXT *tspContext) +{ + struct tsp_object *obj; + + if ((obj = obj_list_get_obj(&encdata_list, hEncdata)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + *tspContext = obj->tspContext; + + obj_list_put(&encdata_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_encdata_get_policy(TSS_HENCDATA hEncData, UINT32 policyType, TSS_HPOLICY *phPolicy) +{ + struct tsp_object *obj; + struct tr_encdata_obj *encdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + encdata = (struct tr_encdata_obj *)obj->data; + + switch (policyType) { + case TSS_POLICY_USAGE: + *phPolicy = encdata->usagePolicy; + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + obj_list_put(&encdata_list); + + return result; +} + +TSS_RESULT +obj_encdata_set_policy(TSS_HENCDATA hEncData, TSS_HPOLICY hPolicy) +{ + struct tsp_object *obj; + struct tr_encdata_obj *encdata; + UINT32 policyType; + TSS_RESULT result = TSS_SUCCESS; + + if ((result = obj_policy_get_type(hPolicy, &policyType))) + return result; + + if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + encdata = (struct tr_encdata_obj *)obj->data; + + switch (policyType) { + case TSS_POLICY_USAGE: + encdata->usagePolicy = hPolicy; + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + obj_list_put(&encdata_list); + + return result; +} + +TSS_RESULT +obj_encdata_get_data(TSS_HENCDATA hEncData, UINT32 *size, BYTE **data) +{ + struct tsp_object *obj; + struct tr_encdata_obj *encdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + encdata = (struct tr_encdata_obj *)obj->data; + + if (encdata->encryptedDataLength == 0) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } else { + *data = calloc_tspi(obj->tspContext, encdata->encryptedDataLength); + if (*data == NULL) { + LogError("malloc of %d bytes failed.", + encdata->encryptedDataLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + *size = encdata->encryptedDataLength; + memcpy(*data, encdata->encryptedData, *size); + } + +done: + obj_list_put(&encdata_list); + + return result; +} + +TSS_RESULT +obj_encdata_get_pcr_digest(TSS_HENCDATA hEncData, + TSS_FLAG pcrInfoType, + TSS_FLAG dir, + UINT32 *size, + BYTE **data) +{ + struct tsp_object *obj; + struct tr_encdata_obj *encdata; + TSS_RESULT result = TSS_SUCCESS; + TPM_DIGEST *digest; + UINT64 offset; + + if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + encdata = (struct tr_encdata_obj *)obj->data; + + if (pcrInfoType != encdata->pcrInfoType) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + switch (pcrInfoType) { + case TSS_PCRS_STRUCT_INFO: + if (dir == TSS_TSPATTRIB_ENCDATAPCR_DIGEST_ATCREATION) + digest = &encdata->pcrInfo.info11.digestAtCreation; + else if (dir == TSS_TSPATTRIB_ENCDATAPCR_DIGEST_ATRELEASE) + digest = &encdata->pcrInfo.info11.digestAtRelease; + else { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + break; + case TSS_PCRS_STRUCT_INFO_LONG: + if (dir == TSS_TSPATTRIB_ENCDATAPCRLONG_DIGEST_ATCREATION) + digest = &encdata->pcrInfo.infolong.digestAtCreation; + else if (dir == TSS_TSPATTRIB_ENCDATAPCRLONG_DIGEST_ATRELEASE) + digest = &encdata->pcrInfo.infolong.digestAtRelease; + else { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + break; + default: + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + *size = sizeof(TPM_DIGEST); + + if ((*data = calloc_tspi(obj->tspContext, *size)) == NULL) { + LogError("malloc of %u bytes failed.", *size); + *size = 0; + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + offset = 0; + Trspi_LoadBlob_DIGEST(&offset, *data, digest); +done: + obj_list_put(&encdata_list); + + return result; +} + +TSS_RESULT +obj_encdata_get_pcr_locality(TSS_HENCDATA hEncData, TSS_FLAG dir, UINT32 *locality) +{ + struct tsp_object *obj; + struct tr_encdata_obj *encdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + encdata = (struct tr_encdata_obj *)obj->data; + + if (encdata->pcrInfoType == TSS_PCRS_STRUCT_INFO_LONG) { + if (dir == TSS_TSPATTRIB_ENCDATAPCRLONG_LOCALITY_ATCREATION) + *locality = encdata->pcrInfo.infolong.localityAtCreation; + else if (dir == TSS_TSPATTRIB_ENCDATAPCRLONG_LOCALITY_ATRELEASE) + *locality = encdata->pcrInfo.infolong.localityAtRelease; + else + result = TSPERR(TSS_E_BAD_PARAMETER); + } else + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + + obj_list_put(&encdata_list); + + return result; +} + +TSS_RESULT +obj_encdata_get_pcr_selection(TSS_HENCDATA hEncData, + TSS_FLAG pcrInfoType, + TSS_FLAG dir, + UINT32 *size, + BYTE **data) +{ + struct tsp_object *obj; + struct tr_encdata_obj *encdata; + TSS_RESULT result = TSS_SUCCESS; + TPM_PCR_SELECTION *selection = NULL; + UINT64 offset; + + if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + encdata = (struct tr_encdata_obj *)obj->data; + + if (pcrInfoType != encdata->pcrInfoType) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + switch (pcrInfoType) { + case TSS_PCRS_STRUCT_INFO: + if (dir == TSS_TSPATTRIB_ENCDATAPCR_SELECTION) + selection = &encdata->pcrInfo.info11.pcrSelection; + break; + case TSS_PCRS_STRUCT_INFO_LONG: + if (dir == TSS_TSPATTRIB_ENCDATAPCRLONG_CREATION_SELECTION) + selection = &encdata->pcrInfo.infolong.creationPCRSelection; + else if (dir == TSS_TSPATTRIB_ENCDATAPCRLONG_RELEASE_SELECTION) + selection = &encdata->pcrInfo.infolong.releasePCRSelection; + else { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + break; + default: + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + *size = sizeof(UINT16) + selection->sizeOfSelect; + + if ((*data = calloc_tspi(obj->tspContext, *size)) == NULL) { + LogError("malloc of %u bytes failed.", *size); + *size = 0; + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + offset = 0; + Trspi_LoadBlob_PCR_SELECTION(&offset, *data, selection); +done: + obj_list_put(&encdata_list); + + return result; +} + +TSS_RESULT +obj_encdata_set_pcr_info(TSS_HENCDATA hEncData, UINT32 pcrInfoType, BYTE *info_blob) +{ + struct tsp_object *obj; + struct tr_encdata_obj *encdata; + TSS_RESULT result = TSS_SUCCESS; + UINT64 offset = 0; + + if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + encdata = (struct tr_encdata_obj *)obj->data; + + switch (pcrInfoType) { + case TSS_PCRS_STRUCT_INFO_LONG: + result = Trspi_UnloadBlob_PCR_INFO_LONG(&offset, info_blob, + &encdata->pcrInfo.infolong); + break; + case TSS_PCRS_STRUCT_INFO: + result = Trspi_UnloadBlob_PCR_INFO(&offset, info_blob, + &encdata->pcrInfo.info11); + break; + default: + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + encdata->pcrInfoType = pcrInfoType; + + /* XXX are we using this anywhere? */ + obj->flags |= TSS_OBJ_FLAG_PCRS; +done: + obj_list_put(&encdata_list); + + return result; +} + +TSS_RESULT +obj_encdata_set_data(TSS_HENCDATA hEncData, UINT32 size, BYTE *data) +{ + struct tsp_object *obj; + struct tr_encdata_obj *encdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + encdata = (struct tr_encdata_obj *)obj->data; + + free(encdata->encryptedData); + encdata->encryptedData = NULL; + encdata->encryptedDataLength = 0; + + if (size > 0) { + if ((encdata->encryptedData = malloc(size)) == NULL) { + LogError("malloc of %u bytes failed.", size); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + encdata->encryptedDataLength = size; + memcpy(encdata->encryptedData, data, size); + } + +done: + obj_list_put(&encdata_list); + + return result; +} + +void +encdata_free(void *data) +{ + struct tr_encdata_obj *encdata = (struct tr_encdata_obj *)data; + + free(encdata->encryptedData); + + switch (encdata->pcrInfoType) { + case TSS_PCRS_STRUCT_INFO: + free(encdata->pcrInfo.info11.pcrSelection.pcrSelect); + break; + case TSS_PCRS_STRUCT_INFO_LONG: + free(encdata->pcrInfo.infolong.creationPCRSelection.pcrSelect); + free(encdata->pcrInfo.infolong.releasePCRSelection.pcrSelect); + break; + default: + /* no PCR data was set */ + break; + } + + free(encdata); +} + +/* remove an individual encdata object from the encdata list with handle + * equal to hObject */ +TSS_RESULT +obj_encdata_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext) +{ + TSS_RESULT result; + + if ((result = obj_list_remove(&encdata_list, &encdata_free, hObject, tspContext))) + return result; + + return TSS_SUCCESS; +} + +void +obj_encdata_remove_policy_refs(TSS_HPOLICY hPolicy, TSS_HCONTEXT tspContext) +{ + struct tsp_object *obj; + struct obj_list *list = &encdata_list; + struct tr_encdata_obj *encdata; + + pthread_mutex_lock(&list->lock); + + for (obj = list->head; obj; obj = obj->next) { + if (obj->tspContext != tspContext) + continue; + + encdata = (struct tr_encdata_obj *)obj->data; + if (encdata->usagePolicy == hPolicy) + encdata->usagePolicy = NULL_HPOLICY; + } + + pthread_mutex_unlock(&list->lock); +} + +#ifdef TSS_BUILD_SEALX +TSS_RESULT +obj_encdata_set_seal_protect_mode(TSS_HENCDATA hEncData, UINT32 protectMode) +{ + struct tsp_object *obj; + struct tr_encdata_obj *encdata; + + if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + encdata = (struct tr_encdata_obj *)obj->data; + + encdata->protectMode = protectMode; + + obj_list_put(&encdata_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_encdata_get_seal_protect_mode(TSS_HENCDATA hEncData, UINT32 *protectMode) +{ + struct tsp_object *obj; + struct tr_encdata_obj *encdata; + + if ((obj = obj_list_get_obj(&encdata_list, hEncData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + encdata = (struct tr_encdata_obj *)obj->data; + + *protectMode = encdata->protectMode; + + obj_list_put(&encdata_list); + + return TSS_SUCCESS; +} +#endif + diff --git a/src/tspi/obj_hash.c b/src/tspi/obj_hash.c new file mode 100644 index 0000000..0925a81 --- /dev/null +++ b/src/tspi/obj_hash.c @@ -0,0 +1,227 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2005, 2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + +TSS_RESULT +obj_hash_add(TSS_HCONTEXT tspContext, UINT32 type, TSS_HOBJECT *phObject) +{ + TSS_RESULT result; + struct tr_hash_obj *hash = calloc(1, sizeof(struct tr_hash_obj)); + + if (hash == NULL) { + LogError("malloc of %zd bytes failed.", + sizeof(struct tr_hash_obj)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + if ((type == TSS_HASH_SHA1) || + (type == TSS_HASH_DEFAULT)) { + hash->type = TSS_HASH_SHA1; + hash->hashSize = 20; + } else if (type == TSS_HASH_OTHER) { + hash->type = TSS_HASH_OTHER; + hash->hashSize = 0; + } + + if ((result = obj_list_add(&hash_list, tspContext, 0, hash, phObject))) { + free(hash); + return result; + } + + return TSS_SUCCESS; +} + +TSS_BOOL +obj_is_hash(TSS_HOBJECT hObject) +{ + TSS_BOOL answer = FALSE; + + if ((obj_list_get_obj(&hash_list, hObject))) { + answer = TRUE; + obj_list_put(&hash_list); + } + + return answer; +} + +TSS_RESULT +obj_hash_get_tsp_context(TSS_HHASH hHash, TSS_HCONTEXT *tspContext) +{ + struct tsp_object *obj; + + if ((obj = obj_list_get_obj(&hash_list, hHash)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + *tspContext = obj->tspContext; + + obj_list_put(&hash_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_hash_set_value(TSS_HHASH hHash, UINT32 size, BYTE *value) +{ + struct tsp_object *obj; + struct tr_hash_obj *hash; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&hash_list, hHash)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + hash = (struct tr_hash_obj *)obj->data; + + if (hash->type != TSS_HASH_OTHER && + size != TCPA_SHA1_160_HASH_LEN) { + result = TSPERR(TSS_E_HASH_INVALID_LENGTH); + goto done; + } + + free(hash->hashData); + + if ((hash->hashData = calloc(1, size)) == NULL) { + LogError("malloc of %d bytes failed.", size); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + hash->hashSize = size; + memcpy(hash->hashData, value, size); + +done: + obj_list_put(&hash_list); + + return result; +} + +TSS_RESULT +obj_hash_get_value(TSS_HHASH hHash, UINT32 *size, BYTE **value) +{ + struct tsp_object *obj; + struct tr_hash_obj *hash; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&hash_list, hHash)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + hash = (struct tr_hash_obj *)obj->data; + + if (hash->hashData == NULL) { + result = TSPERR(TSS_E_HASH_NO_DATA); + goto done; + } + + if ((*value = calloc_tspi(obj->tspContext, hash->hashSize)) == NULL) { + LogError("malloc of %d bytes failed.", hash->hashSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + *size = hash->hashSize; + memcpy(*value, hash->hashData, *size); + +done: + obj_list_put(&hash_list); + + return result; +} + +TSS_RESULT +obj_hash_update_value(TSS_HHASH hHash, UINT32 size, BYTE *data) +{ + struct tsp_object *obj; + struct tr_hash_obj *hash; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&hash_list, hHash)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + hash = (struct tr_hash_obj *)obj->data; + + if (hash->type != TSS_HASH_SHA1 && + hash->type != TSS_HASH_DEFAULT) { + result = TSPERR(TSS_E_FAIL); + goto done; + } + + if (hash->hashUpdateBuffer == NULL) { + hash->hashUpdateBuffer = calloc(1, size); + if (hash->hashUpdateBuffer == NULL) { + LogError("malloc of %u bytes failed.", size); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + } else { + hash->hashUpdateBuffer = realloc(hash->hashUpdateBuffer, + size + hash->hashUpdateSize); + + if (hash->hashUpdateBuffer == NULL) { + LogError("malloc of %u bytes failed.", size + hash->hashUpdateSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + } + + memcpy(&hash->hashUpdateBuffer[hash->hashUpdateSize], data, size); + hash->hashUpdateSize += size; + + if (hash->hashData == NULL) { + hash->hashData = calloc(1, TCPA_SHA1_160_HASH_LEN); + if (hash->hashData == NULL) { + LogError("malloc of %d bytes failed.", TCPA_SHA1_160_HASH_LEN); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + } + + result = Trspi_Hash(TSS_HASH_SHA1, hash->hashUpdateSize, hash->hashUpdateBuffer, + hash->hashData); + +done: + obj_list_put(&hash_list); + + return result; +} + +void +__tspi_hash_free(void *data) +{ + struct tr_hash_obj *hash = (struct tr_hash_obj *)data; + + free(hash->hashData); + free(hash->hashUpdateBuffer); + free(hash); +} + +/* + * remove hash object hObject from the list + */ +TSS_RESULT +obj_hash_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext) +{ + TSS_RESULT result; + + if ((result = obj_list_remove(&hash_list, &__tspi_hash_free, hObject, tspContext))) + return result; + + return TSS_SUCCESS; +} + diff --git a/src/tspi/obj_migdata.c b/src/tspi/obj_migdata.c new file mode 100644 index 0000000..aee4cba --- /dev/null +++ b/src/tspi/obj_migdata.c @@ -0,0 +1,1124 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +void +migdata_free(void *data) +{ + struct tr_migdata_obj *migdata = (struct tr_migdata_obj *)data; + + free(migdata); +} + +TSS_BOOL +obj_is_migdata(TSS_HOBJECT hObject) +{ + TSS_BOOL answer = FALSE; + + if ((obj_list_get_obj(&migdata_list, hObject))) { + answer = TRUE; + obj_list_put(&migdata_list); + } + + return answer; +} + +TSS_RESULT +obj_migdata_add(TSS_HCONTEXT hContext, TSS_HOBJECT *phObject) +{ + TSS_RESULT result; + struct tr_migdata_obj *migdata = calloc(1, sizeof(struct tr_migdata_obj)); + + if (migdata == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(struct tr_migdata_obj)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + if ((result = obj_list_add(&migdata_list, hContext, 0, migdata, phObject))) { + free(migdata); + return result; + } + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_migdata_remove(TSS_HMIGDATA hMigData, TSS_HCONTEXT hContext) +{ + TSS_RESULT result; + + if ((result = obj_list_remove(&migdata_list, &migdata_free, hMigData, hContext))) + return result; + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_migdata_get_tsp_context(TSS_HMIGDATA hMigData, TSS_HCONTEXT *hContext) +{ + struct tsp_object *obj; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + *hContext = obj->tspContext; + + obj_list_put(&migdata_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_migdata_set_migrationblob(TSS_HMIGDATA hMigData, UINT32 whichOne, UINT32 blobSize, BYTE *blob) +{ + TSS_RESULT result; + + switch (whichOne) { + case TSS_MIGATTRIB_MIG_MSALIST_PUBKEY_BLOB: + result = obj_migdata_set_msa_pubkey(hMigData, blobSize, blob); + break; + case TSS_MIGATTRIB_MIG_AUTHORITY_PUBKEY_BLOB: + result = obj_migdata_set_ma_pubkey(hMigData, blobSize, blob); + break; + case TSS_MIGATTRIB_MIG_DESTINATION_PUBKEY_BLOB: + result = obj_migdata_set_dest_pubkey(hMigData, blobSize, blob); + break; + case TSS_MIGATTRIB_MIG_SOURCE_PUBKEY_BLOB: + result = obj_migdata_set_src_pubkey(hMigData, blobSize, blob); + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + return result; +} + +TSS_RESULT +obj_migdata_get_migrationblob(TSS_HMIGDATA hMigData, UINT32 whichOne, UINT32 *blobSize, BYTE **blob) +{ + TSS_RESULT result; + + switch (whichOne) { + case TSS_MIGATTRIB_MIG_XOR_BLOB: + result = obj_migdata_get_blob(hMigData, blobSize, blob); + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + return result; +} + +TSS_RESULT +obj_migdata_set_authoritydata(TSS_HMIGDATA hMigData, UINT32 whichOne, UINT32 blobSize, BYTE *blob) +{ + TSS_RESULT result; + + switch (whichOne) { + case TSS_MIGATTRIB_AUTHORITY_DIGEST: + result = obj_migdata_set_msa_digest(hMigData, blobSize, blob); + break; + case TSS_MIGATTRIB_AUTHORITY_APPROVAL_HMAC: + result = obj_migdata_set_msa_hmac(hMigData, blobSize, blob); + break; + case TSS_MIGATTRIB_AUTHORITY_MSALIST: + result = obj_migdata_set_msa_list(hMigData, blobSize, blob); + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + return result; +} + +TSS_RESULT +obj_migdata_get_authoritydata(TSS_HMIGDATA hMigData, UINT32 whichOne, UINT32 *blobSize, BYTE **blob) +{ + TSS_RESULT result; + + switch (whichOne) { + case TSS_MIGATTRIB_AUTHORITY_DIGEST: + result = obj_migdata_get_msa_digest(hMigData, blobSize, blob); + break; + case TSS_MIGATTRIB_AUTHORITY_APPROVAL_HMAC: + result = obj_migdata_get_msa_hmac(hMigData, blobSize, blob); + break; + case TSS_MIGATTRIB_AUTHORITY_MSALIST: + result = obj_migdata_get_msa_list(hMigData, blobSize, blob); + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + return result; +} + +TSS_RESULT +obj_migdata_set_migauthdata(TSS_HMIGDATA hMigData, UINT32 whichOne, UINT32 blobSize, BYTE *blob) +{ + TSS_RESULT result; + + switch (whichOne) { + case TSS_MIGATTRIB_MIG_AUTH_AUTHORITY_DIGEST: + result = obj_migdata_set_ma_digest(hMigData, blobSize, blob); + break; + case TSS_MIGATTRIB_MIG_AUTH_DESTINATION_DIGEST: + result = obj_migdata_set_dest_digest(hMigData, blobSize, blob); + break; + case TSS_MIGATTRIB_MIG_AUTH_SOURCE_DIGEST: + result = obj_migdata_set_src_digest(hMigData, blobSize, blob); + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + return result; +} + +TSS_RESULT +obj_migdata_get_migauthdata(TSS_HMIGDATA hMigData, UINT32 whichOne, UINT32 *blobSize, BYTE **blob) +{ + TSS_RESULT result; + + switch (whichOne) { + case TSS_MIGATTRIB_MIG_AUTH_AUTHORITY_DIGEST: + result = obj_migdata_get_ma_digest(hMigData, blobSize, blob); + break; + case TSS_MIGATTRIB_MIG_AUTH_DESTINATION_DIGEST: + result = obj_migdata_get_dest_digest(hMigData, blobSize, blob); + break; + case TSS_MIGATTRIB_MIG_AUTH_SOURCE_DIGEST: + result = obj_migdata_get_src_digest(hMigData, blobSize, blob); + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + return result; +} + +TSS_RESULT +obj_migdata_set_ticketdata(TSS_HMIGDATA hMigData, UINT32 whichOne, UINT32 blobSize, BYTE *blob) +{ + TSS_RESULT result; + + switch (whichOne) { + case TSS_MIGATTRIB_TICKET_SIG_DIGEST: + result = obj_migdata_set_sig_data(hMigData, blobSize, blob); + break; + case TSS_MIGATTRIB_TICKET_SIG_VALUE: + result = obj_migdata_set_sig_value(hMigData, blobSize, blob); + break; + case TSS_MIGATTRIB_TICKET_SIG_TICKET: + result = obj_migdata_set_sig_ticket(hMigData, blobSize, blob); + break; + case TSS_MIGATTRIB_TICKET_RESTRICT_TICKET: + result = obj_migdata_set_cmk_auth(hMigData, blobSize, blob); + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + return result; +} + +TSS_RESULT +obj_migdata_get_ticketdata(TSS_HMIGDATA hMigData, UINT32 whichOne, UINT32 *blobSize, BYTE **blob) +{ + TSS_RESULT result; + + switch (whichOne) { + case TSS_MIGATTRIB_TICKET_SIG_TICKET: + result = obj_migdata_get_sig_ticket(hMigData, blobSize, blob); + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + return result; +} + +TSS_RESULT +obj_migdata_set_ticket_blob(TSS_HMIGDATA hMigData, UINT32 migTicketSize, BYTE *migTicket) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + migdata->migTicketSize = 0; + free(migdata->migTicket); + if ((migdata->migTicket = malloc(migTicketSize)) == NULL) { + LogError("malloc of %u bytes failed.", migTicketSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(migdata->migTicket, migTicket, migTicketSize); + migdata->migTicketSize = migTicketSize; + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_get_ticket_blob(TSS_HMIGDATA hMigData, UINT32 *migTicketSize, BYTE **migTicket) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if ((*migTicket = calloc_tspi(obj->tspContext, migdata->migTicketSize)) == NULL) { + LogError("malloc of %u bytes failed.", migdata->migTicketSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(*migTicket, migdata->migTicket, migdata->migTicketSize); + *migTicketSize = migdata->migTicketSize; + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_set_msa_list(TSS_HMIGDATA hMigData, UINT32 msaListSize, BYTE *msaList) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + UINT32 i, count, size; + TPM_DIGEST *digest; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + count = msaListSize / sizeof(digest->digest); + size = count * sizeof(*digest); + + migdata->msaList.MSAlist = 0; + free(migdata->msaList.migAuthDigest); + if ((migdata->msaList.migAuthDigest = malloc(size)) == NULL) { + LogError("malloc of %u bytes failed.", size); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + digest = migdata->msaList.migAuthDigest; + for (i = 0; i < count; i++) { + memcpy(digest->digest, msaList, sizeof(digest->digest)); + msaList += sizeof(digest->digest); + digest++; + } + migdata->msaList.MSAlist = count; + + result = obj_migdata_calc_msa_digest(migdata); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_get_msa_list(TSS_HMIGDATA hMigData, UINT32 *size, BYTE **msaList) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + UINT32 i; + TPM_DIGEST *digest; + BYTE *tmpMsaList; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + *size = migdata->msaList.MSAlist * sizeof(migdata->msaList.migAuthDigest->digest); + if ((*msaList = calloc_tspi(obj->tspContext, *size)) == NULL) { + LogError("malloc of %u bytes failed.", *size); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + tmpMsaList = *msaList; + digest = migdata->msaList.migAuthDigest; + for (i = 0; i < migdata->msaList.MSAlist; i++) { + memcpy(tmpMsaList, digest->digest, sizeof(digest->digest)); + tmpMsaList += sizeof(digest->digest); + digest++; + } + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_set_msa_pubkey(TSS_HMIGDATA hMigData, UINT32 blobSize, BYTE *pubKeyBlob) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + UINT32 size; + TPM_DIGEST msaDigest; + TPM_DIGEST *digest; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if ((result = obj_migdata_calc_pubkey_digest(blobSize, pubKeyBlob, &msaDigest))) + goto done; + + size = (migdata->msaList.MSAlist + 1) * sizeof(*digest); + if ((migdata->msaList.migAuthDigest = realloc(migdata->msaList.migAuthDigest, size)) == NULL) { + LogError("malloc of %u bytes failed.", size); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + digest = migdata->msaList.migAuthDigest + migdata->msaList.MSAlist; + *digest = msaDigest; + migdata->msaList.MSAlist++; + + result = obj_migdata_calc_msa_digest(migdata); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_set_msa_digest(TSS_HMIGDATA hMigData, UINT32 digestSize, BYTE *digest) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if (digestSize != sizeof(migdata->msaDigest.digest)) { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + memcpy(migdata->msaDigest.digest, digest, sizeof(migdata->msaDigest.digest)); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_get_msa_digest(TSS_HMIGDATA hMigData, UINT32 *digestSize, BYTE **digest) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if ((*digest = calloc_tspi(obj->tspContext, sizeof(migdata->msaDigest.digest))) == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(migdata->msaDigest.digest)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(*digest, migdata->msaDigest.digest, sizeof(migdata->msaDigest.digest)); + *digestSize = sizeof(migdata->msaDigest.digest); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_get_msa_list_blob(TSS_HMIGDATA hMigData, UINT32 *blobSize, BYTE **msaListBlob) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + UINT64 offset; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + offset = 0; + Trspi_LoadBlob_MSA_COMPOSITE(&offset, NULL, &migdata->msaList); + + *blobSize = offset; + if ((*msaListBlob = calloc_tspi(obj->tspContext, *blobSize)) == NULL) { + LogError("malloc of %u bytes failed.", *blobSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + offset = 0; + Trspi_LoadBlob_MSA_COMPOSITE(&offset, *msaListBlob, &migdata->msaList); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_set_msa_hmac(TSS_HMIGDATA hMigData, UINT32 hmacSize, BYTE *hmac) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if (hmacSize != sizeof(migdata->msaHmac.digest)) { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + memcpy(migdata->msaHmac.digest, hmac, sizeof(migdata->msaHmac.digest)); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_get_msa_hmac(TSS_HMIGDATA hMigData, UINT32 *hmacSize, BYTE **hmac) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if ((*hmac = calloc_tspi(obj->tspContext, sizeof(migdata->msaHmac.digest))) == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(migdata->msaHmac.digest)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(*hmac, migdata->msaHmac.digest, sizeof(migdata->msaHmac.digest)); + *hmacSize = sizeof(migdata->msaHmac.digest); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_set_ma_pubkey(TSS_HMIGDATA hMigData, UINT32 blobSize, BYTE *pubKeyBlob) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TPM_DIGEST pubKeyDigest; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if ((result = obj_migdata_calc_pubkey_digest(blobSize, pubKeyBlob, &pubKeyDigest))) + goto done; + + migdata->maDigest = pubKeyDigest; + + obj_migdata_calc_sig_data_digest(migdata); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_set_ma_digest(TSS_HMIGDATA hMigData, UINT32 digestSize, BYTE *digest) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if (digestSize != sizeof(migdata->maDigest.digest)) { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + memcpy(migdata->maDigest.digest, digest, sizeof(migdata->maDigest.digest)); + + obj_migdata_calc_sig_data_digest(migdata); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_get_ma_digest(TSS_HMIGDATA hMigData, UINT32 *digestSize, BYTE **digest) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if ((*digest = calloc_tspi(obj->tspContext, sizeof(migdata->maDigest.digest))) == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(migdata->maDigest.digest)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(*digest, migdata->maDigest.digest, sizeof(migdata->maDigest.digest)); + *digestSize = sizeof(migdata->maDigest.digest); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_set_dest_pubkey(TSS_HMIGDATA hMigData, UINT32 blobSize, BYTE *pubKeyBlob) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TPM_DIGEST pubKeyDigest; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if ((result = obj_migdata_calc_pubkey_digest(blobSize, pubKeyBlob, &pubKeyDigest))) + goto done; + + migdata->destDigest = pubKeyDigest; + + obj_migdata_calc_sig_data_digest(migdata); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_set_dest_digest(TSS_HMIGDATA hMigData, UINT32 digestSize, BYTE *digest) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if (digestSize != sizeof(migdata->destDigest.digest)) { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + memcpy(migdata->destDigest.digest, digest, sizeof(migdata->destDigest.digest)); + + obj_migdata_calc_sig_data_digest(migdata); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_get_dest_digest(TSS_HMIGDATA hMigData, UINT32 *digestSize, BYTE **digest) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if ((*digest = calloc_tspi(obj->tspContext, sizeof(migdata->destDigest.digest))) == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(migdata->destDigest.digest)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(*digest, migdata->destDigest.digest, sizeof(migdata->destDigest.digest)); + *digestSize = sizeof(migdata->destDigest.digest); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_set_src_pubkey(TSS_HMIGDATA hMigData, UINT32 blobSize, BYTE *pubKeyBlob) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TPM_DIGEST pubKeyDigest; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if ((result = obj_migdata_calc_pubkey_digest(blobSize, pubKeyBlob, &pubKeyDigest))) + goto done; + + migdata->srcDigest = pubKeyDigest; + + obj_migdata_calc_sig_data_digest(migdata); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_set_src_digest(TSS_HMIGDATA hMigData, UINT32 digestSize, BYTE *digest) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if (digestSize != sizeof(migdata->srcDigest.digest)) { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + memcpy(migdata->srcDigest.digest, digest, sizeof(migdata->srcDigest.digest)); + + obj_migdata_calc_sig_data_digest(migdata); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_get_src_digest(TSS_HMIGDATA hMigData, UINT32 *digestSize, BYTE **digest) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if ((*digest = calloc_tspi(obj->tspContext, sizeof(migdata->srcDigest.digest))) == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(migdata->srcDigest.digest)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(*digest, migdata->srcDigest.digest, sizeof(migdata->srcDigest.digest)); + *digestSize = sizeof(migdata->srcDigest.digest); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_set_cmk_auth(TSS_HMIGDATA hMigData, UINT32 digestsSize, BYTE *digests) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if (digestsSize != (sizeof(migdata->maDigest.digest) + + sizeof(migdata->destDigest.digest) + + sizeof(migdata->srcDigest.digest))) { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + memcpy(migdata->maDigest.digest, digests, sizeof(migdata->maDigest.digest)); + digests += sizeof(migdata->maDigest.digest); + memcpy(migdata->destDigest.digest, digests, sizeof(migdata->destDigest.digest)); + digests += sizeof(migdata->destDigest.digest); + memcpy(migdata->srcDigest.digest, digests, sizeof(migdata->srcDigest.digest)); + + obj_migdata_calc_sig_data_digest(migdata); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_get_cmk_auth(TSS_HMIGDATA hMigData, TPM_CMK_AUTH *cmkAuth) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + cmkAuth->migrationAuthorityDigest = migdata->maDigest; + cmkAuth->destinationKeyDigest = migdata->destDigest; + cmkAuth->sourceKeyDigest = migdata->srcDigest; + + obj_list_put(&migdata_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_migdata_get_cmk_auth_blob(TSS_HMIGDATA hMigData, UINT32 *blobSize, BYTE **cmkAuthBlob) +{ + struct tsp_object *obj; + TPM_CMK_AUTH cmkAuth; + UINT64 offset; + TSS_RESULT result; + + if ((result = obj_migdata_get_cmk_auth(hMigData, &cmkAuth))) + return result; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + offset = 0; + Trspi_LoadBlob_CMK_AUTH(&offset, NULL, &cmkAuth); + + *blobSize = offset; + if ((*cmkAuthBlob = calloc_tspi(obj->tspContext, *blobSize)) == NULL) { + LogError("malloc of %u bytes failed.", *blobSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + offset = 0; + Trspi_LoadBlob_CMK_AUTH(&offset, *cmkAuthBlob, &cmkAuth); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_set_sig_data(TSS_HMIGDATA hMigData, UINT32 sigDataSize, BYTE *sigData) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if (sigDataSize != sizeof(migdata->sigData.digest)) { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + memcpy(migdata->sigData.digest, sigData, sizeof(migdata->sigData.digest)); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_get_sig_data(TSS_HMIGDATA hMigData, UINT32 *sigDataSize, BYTE **sigData) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if ((*sigData = calloc_tspi(obj->tspContext, sizeof(migdata->sigData.digest))) == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(migdata->sigData.digest)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(*sigData, migdata->sigData.digest, sizeof(migdata->sigData.digest)); + *sigDataSize = sizeof(migdata->sigData.digest); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_set_sig_value(TSS_HMIGDATA hMigData, UINT32 sigValueSize, BYTE *sigValue) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + migdata->sigValueSize = 0; + free(migdata->sigValue); + if ((migdata->sigValue = malloc(sigValueSize)) == NULL) { + LogError("malloc of %u bytes failed.", sigValueSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(migdata->sigValue, sigValue, sigValueSize); + migdata->sigValueSize = sigValueSize; + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_get_sig_value(TSS_HMIGDATA hMigData, UINT32 *sigValueSize, BYTE **sigValue) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if ((*sigValue = calloc_tspi(obj->tspContext, migdata->sigValueSize)) == NULL) { + LogError("malloc of %u bytes failed.", migdata->sigValueSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(*sigValue, migdata->sigValue, migdata->sigValueSize); + *sigValueSize = migdata->sigValueSize; + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_set_sig_ticket(TSS_HMIGDATA hMigData, UINT32 sigTicketSize, BYTE *sigTicket) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if (sigTicketSize != sizeof(migdata->sigTicket.digest)) { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + memcpy(migdata->sigTicket.digest, sigTicket, sizeof(migdata->sigTicket.digest)); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_get_sig_ticket(TSS_HMIGDATA hMigData, UINT32 *sigTicketSize, BYTE **sigTicket) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if ((*sigTicket = calloc_tspi(obj->tspContext, sizeof(migdata->sigTicket.digest))) == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(migdata->sigTicket.digest)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(*sigTicket, migdata->sigTicket.digest, sizeof(migdata->sigTicket.digest)); + *sigTicketSize = sizeof(migdata->sigTicket.digest); + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_set_blob(TSS_HMIGDATA hMigData, UINT32 blobSize, BYTE *blob) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + migdata->blobSize = 0; + free(migdata->blob); + if ((migdata->blob = malloc(blobSize)) == NULL) { + LogError("malloc of %u bytes failed.", blobSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(migdata->blob, blob, blobSize); + migdata->blobSize = blobSize; + +done: + obj_list_put(&migdata_list); + + return result; +} + +TSS_RESULT +obj_migdata_get_blob(TSS_HMIGDATA hMigData, UINT32 *blobSize, BYTE **blob) +{ + struct tsp_object *obj; + struct tr_migdata_obj *migdata; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&migdata_list, hMigData)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + migdata = (struct tr_migdata_obj *)obj->data; + + if ((*blob = calloc_tspi(obj->tspContext, migdata->blobSize)) == NULL) { + LogError("malloc of %u bytes failed.", migdata->blobSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(*blob, migdata->blob, migdata->blobSize); + *blobSize = migdata->blobSize; + +done: + obj_list_put(&migdata_list); + + return result; +} + + +TSS_RESULT +obj_migdata_calc_pubkey_digest(UINT32 blobSize, BYTE *blob, TPM_DIGEST *digest) +{ + Trspi_HashCtx hashCtx; + TSS_RESULT result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_HashUpdate(&hashCtx, blobSize, blob); + result |= Trspi_HashFinal(&hashCtx, digest->digest); + + return result; +} + +TSS_RESULT +obj_migdata_calc_msa_digest(struct tr_migdata_obj *migdata) +{ + Trspi_HashCtx hashCtx; + TSS_RESULT result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_MSA_COMPOSITE(&hashCtx, &migdata->msaList); + result |= Trspi_HashFinal(&hashCtx, migdata->msaDigest.digest); + + return result; +} + +TSS_RESULT +obj_migdata_calc_sig_data_digest(struct tr_migdata_obj *migdata) +{ + Trspi_HashCtx hashCtx; + TSS_RESULT result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, migdata->maDigest.digest); + result |= Trspi_Hash_DIGEST(&hashCtx, migdata->destDigest.digest); + result |= Trspi_Hash_DIGEST(&hashCtx, migdata->srcDigest.digest); + result |= Trspi_HashFinal(&hashCtx, migdata->sigData.digest); + + return result; +} diff --git a/src/tspi/obj_nv.c b/src/tspi/obj_nv.c new file mode 100644 index 0000000..31a3153 --- /dev/null +++ b/src/tspi/obj_nv.c @@ -0,0 +1,746 @@ +/* + * The Initial Developer of the Original Code is Intel Corporation. + * Portions created by Intel Corporation are Copyright (C) 2007 Intel Corporation. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Common Public License as published by + * IBM Corporation; either version 1 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Common Public License for more details. + * + * You should have received a copy of the Common Public License + * along with this program; if not, a copy can be viewed at + * http://www.opensource.org/licenses/cpl1.0.php. + * + * trousers - An open source TCG Software Stack + * + * Author: james.xu@intel.com Rossey.liu@intel.com + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + +TSS_RESULT +obj_nvstore_add(TSS_HCONTEXT tspContext, TSS_HOBJECT *phObject) +{ + TSS_RESULT result; + struct tr_nvstore_obj *nvstore = calloc(1, sizeof(struct tr_nvstore_obj)); + + if (nvstore == NULL) { + LogError("malloc of %zd bytes failed.", + sizeof(struct tr_nvstore_obj)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + if ((result = obj_list_add(&nvstore_list, tspContext, 0, nvstore, phObject))) { + free(nvstore); + return result; + } + + return TSS_SUCCESS; +} + +TSS_BOOL +obj_is_nvstore(TSS_HOBJECT hObject) +{ + TSS_BOOL answer = FALSE; + + if ((obj_list_get_obj(&nvstore_list, hObject))) { + answer = TRUE; + obj_list_put(&nvstore_list); + } + + return answer; +} + +void +nvstore_free(void *data) +{ + struct tr_nvstore_obj *nvstore = (struct tr_nvstore_obj *)data; + + free(nvstore); +} + +TSS_RESULT +obj_nvstore_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext) +{ + TSS_RESULT result; + + if ((result = obj_list_remove(&nvstore_list, &nvstore_free, hObject, tspContext))) + return result; + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_nvstore_get_tsp_context(TSS_HNVSTORE hNvstore, TSS_HCONTEXT * tspContext) +{ + struct tsp_object *obj; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + *tspContext = obj->tspContext; + + obj_list_put(&nvstore_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_nvstore_set_index(TSS_HNVSTORE hNvstore, UINT32 index) +{ + struct tsp_object *obj; + struct tr_nvstore_obj *nvstore; + TSS_RESULT result=TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + nvstore = (struct tr_nvstore_obj *)obj->data; + + nvstore->nvIndex = index; + + obj_list_put(&nvstore_list); + + return result; +} + +TSS_RESULT +obj_nvstore_get_index(TSS_HNVSTORE hNvstore, UINT32 * index) +{ + struct tsp_object *obj; + struct tr_nvstore_obj *nvstore; + TSS_RESULT result=TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + nvstore = (struct tr_nvstore_obj *)obj->data; + + *index = nvstore->nvIndex; + + obj_list_put(&nvstore_list); + + return result; +} + +TSS_RESULT +obj_nvstore_set_datasize(TSS_HNVSTORE hNvstore, UINT32 datasize) +{ + struct tsp_object *obj; + struct tr_nvstore_obj *nvstore; + TSS_RESULT result=TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + nvstore = (struct tr_nvstore_obj *)obj->data; + + nvstore->dataSize= datasize; + + obj_list_put(&nvstore_list); + + return result; +} + +TSS_RESULT +obj_nvstore_get_datasize(TSS_HNVSTORE hNvstore, UINT32 * datasize) +{ + struct tsp_object *obj; + struct tr_nvstore_obj *nvstore; + TSS_RESULT result=TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + nvstore = (struct tr_nvstore_obj *)obj->data; + + *datasize = nvstore->dataSize; + + obj_list_put(&nvstore_list); + + return result; +} + +TSS_RESULT +obj_nvstore_set_permission(TSS_HNVSTORE hNvstore, UINT32 permission) +{ + struct tsp_object *obj; + struct tr_nvstore_obj *nvstore; + TSS_RESULT result=TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + nvstore = (struct tr_nvstore_obj *)obj->data; + + nvstore->permission.attributes= permission; + + obj_list_put(&nvstore_list); + + return result; +} + +TSS_RESULT +obj_nvstore_get_permission_from_tpm(TSS_HNVSTORE hNvstore, UINT32 * permission) +{ + BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE] = {0}; + UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; + UINT32 offset; + UINT16 pcrread_sizeOfSelect; + UINT16 pcrwrite_sizeOfSelect; + TPM_NV_ATTRIBUTES nv_attributes_value; + TSS_HCONTEXT tspContext; + TSS_RESULT result; + + if((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) + return result; + + if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext))) + return result; + + offset = 0; + offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); + pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + + offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH); + pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + + offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH); + + nv_attributes_value.attributes = Decode_UINT32(nv_data_public + + offset + sizeof(TPM_STRUCTURE_TAG)); + *permission = nv_attributes_value.attributes; + + return result; +} + +TSS_RESULT +obj_nvstore_get_permission(TSS_HNVSTORE hNvstore, UINT32 * permission) +{ + struct tsp_object *obj; + struct tr_nvstore_obj *nvstore; + TSS_RESULT result=TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + nvstore = (struct tr_nvstore_obj *)obj->data; + + *permission = nvstore->permission.attributes; + + obj_list_put(&nvstore_list); + + return result; +} + +TSS_RESULT +obj_nvstore_set_policy(TSS_HNVSTORE hNvstore, TSS_HPOLICY hPolicy) +{ + struct tsp_object *obj; + struct tr_nvstore_obj *nvstore; + UINT32 policyType; + TSS_RESULT result = TSS_SUCCESS; + + if ((result = obj_policy_get_type(hPolicy, &policyType))) + return result; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + nvstore = (struct tr_nvstore_obj *)obj->data; + + switch (policyType) { + case TSS_POLICY_USAGE: + nvstore->policy = hPolicy; + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + obj_list_put(&nvstore_list); + + return result; +} + +TSS_RESULT +obj_nvstore_get_policy(TSS_HNVSTORE hNvstore, UINT32 policyType, TSS_HPOLICY *phPolicy) +{ + struct tsp_object *obj; + struct tr_nvstore_obj *nvstore; + TSS_RESULT result=TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + nvstore = (struct tr_nvstore_obj *)obj->data; + + switch (policyType) { + case TSS_POLICY_USAGE: + *phPolicy = nvstore->policy; + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + obj_list_put(&nvstore_list); + + return result; +} + +TSS_RESULT +obj_nvstore_get_datapublic(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE *nv_data_public) +{ + struct tsp_object *obj; + TSS_HCONTEXT hContext; + TSS_HTPM hTpm; + TSS_RESULT result; + struct tr_nvstore_obj *nvstore; + UINT32 uiResultLen; + BYTE *pResult; + UINT32 i; + TPM_BOOL defined_index = FALSE; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + hContext = obj->tspContext; + nvstore = (struct tr_nvstore_obj *)obj->data; + + if ((result = obj_tpm_get(hContext, &hTpm))) + goto out; + + if ((result = Tspi_TPM_GetCapability(hTpm, TSS_TPMCAP_NV_LIST, 0, + NULL, &uiResultLen, &pResult))) { + goto out; + } + + for (i = 0; i < uiResultLen/sizeof(UINT32); i++) { + if (nvstore->nvIndex == Decode_UINT32(pResult + i * sizeof(UINT32))) { + defined_index = TRUE; + break; + } + } + + free_tspi(hContext, pResult); + + if (!defined_index) { + result = TSPERR(TPM_E_BADINDEX); + goto out; + } + + if ((result = Tspi_TPM_GetCapability(hTpm, TSS_TPMCAP_NV_INDEX, + sizeof(UINT32), (BYTE *)(&(nvstore->nvIndex)), + &uiResultLen, &pResult))) { + LogDebug("get the index capability error"); + goto out; + } + + if (uiResultLen > *size) { + free_tspi(hContext, pResult); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto out; + } + *size = uiResultLen; + memcpy(nv_data_public, pResult, uiResultLen); + free_tspi(hContext, pResult); + +out: + obj_list_put(&nvstore_list); + return result; +} + +TSS_RESULT +obj_nvstore_get_readdigestatrelease(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE **data) +{ + BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE]; + UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; + UINT32 offset; + UINT16 pcrread_sizeOfSelect; + TSS_HCONTEXT tspContext; + TSS_RESULT result; + + if((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) + return result; + + if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext))) + return result; + + *size = sizeof(TPM_COMPOSITE_HASH); + *data = calloc_tspi(tspContext, *size); + if (*data == NULL) { + LogError("malloc of %u bytes failed.", *size); + result = TSPERR(TSS_E_OUTOFMEMORY); + return result; + } + + offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); + pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + sizeof(TPM_LOCALITY_SELECTION); + memcpy(*data, nv_data_public + offset, sizeof(TPM_COMPOSITE_HASH)); + + return result; +} + +TSS_RESULT +obj_nvstore_get_readpcrselection(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE **data) +{ + BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE]; + UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; + UINT32 offset; + UINT16 pcrread_sizeOfSelect; + TSS_HCONTEXT tspContext; + TSS_RESULT result; + + if((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) + return result; + + if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext))) + return result; + + offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); + pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + + *size = sizeof(UINT16) + pcrread_sizeOfSelect; + *data = calloc_tspi(tspContext, *size); + if (*data == NULL) { + LogError("malloc of %u bytes failed.", *size); + result = TSPERR(TSS_E_OUTOFMEMORY); + return result; + } + + memcpy(*data, nv_data_public + offset, *size); + + return result; +} + +TSS_RESULT +obj_nvstore_get_writedigestatrelease(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE **data) +{ + BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE]; + UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; + UINT32 offset; + UINT16 pcrread_sizeOfSelect; + TSS_HCONTEXT tspContext; + TSS_RESULT result; + + if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) + return result; + + if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext))) + return result; + + *size = sizeof(TPM_COMPOSITE_HASH); + *data = calloc_tspi(tspContext, *size); + if (*data == NULL) { + LogError("malloc of %u bytes failed.", *size); + result = TSPERR(TSS_E_OUTOFMEMORY); + return result; + } + + offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); + pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH); + + Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + sizeof(TPM_LOCALITY_SELECTION); + memcpy(*data, nv_data_public + offset, sizeof(TPM_COMPOSITE_HASH)); + + return result; +} + +TSS_RESULT +obj_nvstore_get_writepcrselection(TSS_HNVSTORE hNvstore, UINT32 *size, BYTE **data) +{ + BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE]; + UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; + UINT32 offset; + UINT16 pcrread_sizeOfSelect; + UINT16 pcrwrite_sizeOfSelect; + TSS_HCONTEXT tspContext; + TSS_RESULT result; + + if((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) + return result; + + if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext))) + return result; + + offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); + pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH); + pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + + *size = sizeof(UINT16) + pcrwrite_sizeOfSelect; + *data = calloc_tspi(tspContext, *size); + if (*data == NULL) { + LogError("malloc of %u bytes failed.", *size); + result = TSPERR(TSS_E_OUTOFMEMORY); + return result; + } + + memcpy(*data, nv_data_public + offset, *size); + return result; +} + +TSS_RESULT +obj_nvstore_get_state_readstclear(TSS_HNVSTORE hNvstore, UINT32 * readstclear) +{ + BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE]; + UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; + UINT32 offset; + UINT16 pcrread_sizeOfSelect; + UINT16 pcrwrite_sizeOfSelect; + TPM_BOOL value; + TSS_RESULT result; + + if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) + return result; + + offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); + pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH); + + pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH) + + sizeof(TPM_NV_ATTRIBUTES); + + value = *((TPM_BOOL *)(nv_data_public + offset)); + + *readstclear = value; + + return result; +} + +TSS_RESULT +obj_nvstore_get_state_writedefine(TSS_HNVSTORE hNvstore, UINT32 * writedefine) +{ + BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE]; + UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; + UINT32 offset; + UINT16 pcrread_sizeOfSelect; + UINT16 pcrwrite_sizeOfSelect; + TPM_BOOL value; + TSS_RESULT result; + + if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) + return result; + + offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); + pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH); + + pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH) + + sizeof(TPM_NV_ATTRIBUTES) + + sizeof(TPM_BOOL) + + sizeof(TPM_BOOL); + + value = *((TPM_BOOL *)(nv_data_public + offset)); + + *writedefine = value; + + return result; +} + +TSS_RESULT +obj_nvstore_get_state_writestclear(TSS_HNVSTORE hNvstore, UINT32 * writestclear) +{ + BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE]; + UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; + UINT32 offset; + UINT16 pcrread_sizeOfSelect; + UINT16 pcrwrite_sizeOfSelect; + TPM_BOOL value; + TSS_RESULT result; + + if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) + return result; + + offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); + pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH); + + pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH) + + sizeof(TPM_NV_ATTRIBUTES) + + sizeof(TPM_BOOL); + + value = *((TPM_BOOL *)(nv_data_public + offset)); + *writestclear = value; + + return result; +} + +TSS_RESULT +obj_nvstore_get_readlocalityatrelease(TSS_HNVSTORE hNvstore, UINT32 * readlocalityatrelease) +{ + BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE]; + UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; + UINT32 offset; + UINT16 pcrread_sizeOfSelect; + TPM_LOCALITY_SELECTION locality_value; + TSS_RESULT result; + + if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) + return result; + + offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); + pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect; + locality_value = *((TPM_LOCALITY_SELECTION *)(nv_data_public + offset)); + *readlocalityatrelease = locality_value; + + return result; +} + +TSS_RESULT +obj_nvstore_get_writelocalityatrelease(TSS_HNVSTORE hNvstore, UINT32 * writelocalityatrelease) +{ + BYTE nv_data_public[MAX_PUBLIC_DATA_SIZE]; + UINT32 data_public_size = MAX_PUBLIC_DATA_SIZE; + UINT32 offset; + UINT16 pcrread_sizeOfSelect; + UINT16 pcrwrite_sizeOfSelect; + TPM_LOCALITY_SELECTION locality_value; + TSS_RESULT result; + + if ((result = obj_nvstore_get_datapublic(hNvstore, &data_public_size, nv_data_public))) + return result; + + offset = sizeof(TPM_STRUCTURE_TAG)+ sizeof(TPM_NV_INDEX); + pcrread_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrread_sizeOfSelect + + sizeof(TPM_LOCALITY_SELECTION) + + sizeof(TPM_COMPOSITE_HASH); + pcrwrite_sizeOfSelect = Decode_UINT16(nv_data_public + offset); + offset = offset + sizeof(UINT16) + pcrwrite_sizeOfSelect; + + locality_value = *((TPM_LOCALITY_SELECTION *)(nv_data_public + offset)); + *writelocalityatrelease = locality_value; + + return result; +} + +TSS_RESULT +obj_nvstore_create_pcrshortinfo(TSS_HNVSTORE hNvstore, + TSS_HPCRS hPcrComposite, + UINT32 *size, + BYTE **data) +{ + struct tsp_object *obj; + BYTE pdata[MAX_PUBLIC_DATA_SIZE]; + UINT32 dataLen; + UINT64 offset; + TSS_HCONTEXT tspContext; + TSS_RESULT result = TSS_SUCCESS; + BYTE* ppbHashData; + UINT32 i; + BYTE digAtRelease[TPM_SHA1_160_HASH_LEN] = { 0, }; + UINT32 tmp_locAtRelease; + TPM_LOCALITY_SELECTION locAtRelease = TPM_LOC_ZERO | TPM_LOC_ONE + | TPM_LOC_TWO | TPM_LOC_THREE| TPM_LOC_FOUR; + BYTE tmp_pcr_select[3] = {0, 0, 0}; + TCPA_PCR_SELECTION pcrSelect = { 3, tmp_pcr_select}; + + if ((obj = obj_list_get_obj(&nvstore_list, hNvstore)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + tspContext = obj->tspContext; + + if (hPcrComposite) { + if ((result = obj_pcrs_get_selection(hPcrComposite, &dataLen, pdata))) { + LogDebug("get_selection error from hReadPcrComposite"); + goto out; + } + + /* the index should not >= 24, so the sizeofselect should not be >3*/ + if (dataLen - sizeof(UINT16) > 3) { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto out; + } + offset = 0; + Trspi_UnloadBlob_PCR_SELECTION(&offset, pdata, &pcrSelect); + + if (pcrSelect.sizeOfSelect != 0) { + if ((result = obj_pcrs_get_digest_at_release(hPcrComposite, + &dataLen, &ppbHashData))) { + LogDebug("get_composite error from hReadPcrComposite"); + goto out; + } + memcpy(digAtRelease, ppbHashData, dataLen); + free_tspi(tspContext, ppbHashData); + } else { + pcrSelect.sizeOfSelect = 3; + pcrSelect.pcrSelect = tmp_pcr_select; + } + + if (pcrSelect.sizeOfSelect < 3) { + for (i = 0; i < pcrSelect.sizeOfSelect; i++) { + tmp_pcr_select[i] = pcrSelect.pcrSelect[i]; + } + pcrSelect.sizeOfSelect = 3; + pcrSelect.pcrSelect = tmp_pcr_select; + } + + if ((result = obj_pcrs_get_locality(hPcrComposite, &tmp_locAtRelease))) + goto out; + locAtRelease = (TPM_LOCALITY_SELECTION)(tmp_locAtRelease & TSS_LOCALITY_MASK); + } + + *size = sizeof(UINT16) + 3 + sizeof(TPM_LOCALITY_SELECTION) + TPM_SHA1_160_HASH_LEN; + *data = calloc_tspi(tspContext, *size); + if (*data == NULL) { + LogError("malloc of %u bytes failed.", *size); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto out; + } + + offset = 0; + Trspi_LoadBlob_PCR_SELECTION(&offset, *data, &pcrSelect); + Trspi_LoadBlob_BYTE(&offset, locAtRelease, *data); + Trspi_LoadBlob(&offset, TPM_SHA1_160_HASH_LEN, *data, digAtRelease); + +out: + obj_list_put(&nvstore_list); + return result; +} + + diff --git a/src/tspi/obj_pcrs.c b/src/tspi/obj_pcrs.c new file mode 100644 index 0000000..5408302 --- /dev/null +++ b/src/tspi/obj_pcrs.c @@ -0,0 +1,904 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2005, 2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +obj_pcrs_add(TSS_HCONTEXT tspContext, UINT32 type, TSS_HOBJECT *phObject) +{ + TSS_RESULT result; + UINT32 ver; + struct tr_pcrs_obj *pcrs; + + if ((pcrs = calloc(1, sizeof(struct tr_pcrs_obj))) == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(struct tr_pcrs_obj)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + if (type == TSS_PCRS_STRUCT_DEFAULT) { + if ((result = obj_context_get_connection_version(tspContext, &ver))) { + free(pcrs); + return result; + } + + switch (ver) { + case TSS_TSPATTRIB_CONTEXT_VERSION_V1_2: + pcrs->type = TSS_PCRS_STRUCT_INFO_LONG; + pcrs->info.infolong.localityAtRelease = TSS_LOCALITY_ALL; + break; + case TSS_TSPATTRIB_CONTEXT_VERSION_V1_1: + /* fall through */ + default: + pcrs->type = TSS_PCRS_STRUCT_INFO; + break; + } + } else + pcrs->type = type; + + if ((result = obj_list_add(&pcrs_list, tspContext, 0, pcrs, phObject))) { + free(pcrs); + return result; + } + + return TSS_SUCCESS; +} + +void +pcrs_free(void *data) +{ + struct tr_pcrs_obj *pcrs = (struct tr_pcrs_obj *)data; + + switch (pcrs->type) { + case TSS_PCRS_STRUCT_INFO: + free(pcrs->info.info11.pcrSelection.pcrSelect); + break; + case TSS_PCRS_STRUCT_INFO_SHORT: + free(pcrs->info.infoshort.pcrSelection.pcrSelect); + break; + case TSS_PCRS_STRUCT_INFO_LONG: + free(pcrs->info.infolong.creationPCRSelection.pcrSelect); + free(pcrs->info.infolong.releasePCRSelection.pcrSelect); + break; + default: + LogDebugFn("Undefined type of PCRs object"); + break; + } + + free(pcrs); +} + +TSS_RESULT +obj_pcrs_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext) +{ + TSS_RESULT result; + + if ((result = obj_list_remove(&pcrs_list, &pcrs_free, hObject, tspContext))) + return result; + + return TSS_SUCCESS; +} + +TSS_BOOL +obj_is_pcrs(TSS_HOBJECT hObject) +{ + TSS_BOOL answer = FALSE; + + if ((obj_list_get_obj(&pcrs_list, hObject))) { + answer = TRUE; + obj_list_put(&pcrs_list); + } + + return answer; +} + +TSS_RESULT +obj_pcrs_get_tsp_context(TSS_HPCRS hPcrs, TSS_HCONTEXT *tspContext) +{ + struct tsp_object *obj; + + if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + *tspContext = obj->tspContext; + + obj_list_put(&pcrs_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_pcrs_get_type(TSS_HPCRS hPcrs, UINT32 *type) +{ + struct tsp_object *obj; + struct tr_pcrs_obj *pcrs; + + if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + pcrs = (struct tr_pcrs_obj *)obj->data; + + *type = pcrs->type; + + obj_list_put(&pcrs_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_pcrs_get_selection(TSS_HPCRS hPcrs, UINT32 *size, BYTE *out) +{ + struct tsp_object *obj; + struct tr_pcrs_obj *pcrs; + TSS_RESULT result = TSS_SUCCESS; + TPM_PCR_SELECTION *tmp; + UINT64 offset = 0; + + if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + pcrs = (struct tr_pcrs_obj *)obj->data; + + switch (pcrs->type) { + case TSS_PCRS_STRUCT_INFO: + tmp = &pcrs->info.info11.pcrSelection; + break; + case TSS_PCRS_STRUCT_INFO_SHORT: + tmp = &pcrs->info.infoshort.pcrSelection; + break; + case TSS_PCRS_STRUCT_INFO_LONG: + tmp = &pcrs->info.infolong.creationPCRSelection; + break; + default: + LogDebugFn("Undefined type of PCRs object"); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + Trspi_LoadBlob_PCR_SELECTION(&offset, out, tmp); + *size = offset; +done: + obj_list_put(&pcrs_list); + + return result; +} + +TSS_RESULT +obj_pcrs_set_values(TSS_HPCRS hPcrs, TPM_PCR_COMPOSITE *pcrComp) +{ + TSS_RESULT result = TSS_SUCCESS; + TPM_PCR_SELECTION *select = &(pcrComp->select); + UINT16 i, val_idx = 0; + + for (i = 0; i < select->sizeOfSelect * 8; i++) { + if (select->pcrSelect[i / 8] & (1 << (i % 8))) { + if ((result = obj_pcrs_set_value(hPcrs, i, TCPA_SHA1_160_HASH_LEN, + (BYTE *)&pcrComp->pcrValue[val_idx]))) + return result; + + val_idx++; + } + } + + return result; +} + +TSS_RESULT +obj_pcrs_set_value(TSS_HPCRS hPcrs, UINT32 idx, UINT32 size, BYTE *value) +{ + struct tsp_object *obj; + struct tr_pcrs_obj *pcrs; + TSS_RESULT result = TSS_SUCCESS; + TPM_PCR_SELECTION *select; + TPM_COMPOSITE_HASH *compHash; + UINT16 bytes_to_hold = (idx / 8) + 1; + + if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + pcrs = (struct tr_pcrs_obj *)obj->data; + + switch(pcrs->type) { + case TSS_PCRS_STRUCT_INFO: + bytes_to_hold = (bytes_to_hold < 2) ? 2 : bytes_to_hold; + select = &pcrs->info.info11.pcrSelection; + compHash = &pcrs->info.info11.digestAtRelease; + break; + case TSS_PCRS_STRUCT_INFO_SHORT: + bytes_to_hold = (bytes_to_hold < 3) ? 3 : bytes_to_hold; + select = &pcrs->info.infoshort.pcrSelection; + compHash = &pcrs->info.infoshort.digestAtRelease; + break; + case TSS_PCRS_STRUCT_INFO_LONG: + bytes_to_hold = (bytes_to_hold < 3) ? 3 : bytes_to_hold; + select = &pcrs->info.infolong.releasePCRSelection; + compHash = &pcrs->info.infolong.digestAtRelease; + break; + default: + LogDebugFn("Undefined type of PCRs object"); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + break; + } + + /* allocate the selection structure */ + if (select->pcrSelect == NULL) { + if ((select->pcrSelect = malloc(bytes_to_hold)) == NULL) { + LogError("malloc of %d bytes failed.", bytes_to_hold); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + select->sizeOfSelect = bytes_to_hold; + memset(select->pcrSelect, 0, bytes_to_hold); + + /* allocate the pcr array */ + if ((pcrs->pcrs = malloc(bytes_to_hold * 8 * + TCPA_SHA1_160_HASH_LEN)) == NULL) { + LogError("malloc of %d bytes failed.", + bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + } else if (select->sizeOfSelect < bytes_to_hold) { + if ((select->pcrSelect = realloc(select->pcrSelect, bytes_to_hold)) == NULL) { + LogError("malloc of %d bytes failed.", bytes_to_hold); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + /* set the newly allocated bytes to 0 */ + memset(&select->pcrSelect[select->sizeOfSelect], 0, + bytes_to_hold - select->sizeOfSelect); + select->sizeOfSelect = bytes_to_hold; + + /* realloc the pcrs array */ + if ((pcrs->pcrs = realloc(pcrs->pcrs, bytes_to_hold * 8 * + sizeof(TPM_PCRVALUE))) == NULL) { + LogError("malloc of %d bytes failed.", + bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + } + + /* set the bit in the selection structure */ + select->pcrSelect[idx / 8] |= (1 << (idx % 8)); + + /* set the value in the pcrs array */ + memcpy(&(pcrs->pcrs[idx]), value, size); + + result = pcrs_calc_composite(select, pcrs->pcrs, compHash); + +done: + obj_list_put(&pcrs_list); + + return result; +} + +TSS_RESULT +obj_pcrs_get_value(TSS_HPCRS hPcrs, UINT32 idx, UINT32 *size, BYTE **value) +{ + struct tsp_object *obj; + struct tr_pcrs_obj *pcrs; + TSS_RESULT result = TSS_SUCCESS; + TPM_PCR_SELECTION *select; + + if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + pcrs = (struct tr_pcrs_obj *)obj->data; + + switch(pcrs->type) { + case TSS_PCRS_STRUCT_INFO: + select = &pcrs->info.info11.pcrSelection; + break; + case TSS_PCRS_STRUCT_INFO_SHORT: + select = &pcrs->info.infoshort.pcrSelection; + break; + case TSS_PCRS_STRUCT_INFO_LONG: + select = &pcrs->info.infolong.creationPCRSelection; + break; + default: + LogDebugFn("Undefined type of PCRs object"); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + break; + } + + if (select->sizeOfSelect < (idx / 8) + 1) { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + + if ((*value = calloc_tspi(obj->tspContext, TCPA_SHA1_160_HASH_LEN)) == NULL) { + LogError("malloc of %d bytes failed.", TCPA_SHA1_160_HASH_LEN); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + *size = TCPA_SHA1_160_HASH_LEN; + memcpy(*value, &pcrs->pcrs[idx], TCPA_SHA1_160_HASH_LEN); + +done: + obj_list_put(&pcrs_list); + + return result; +} + +TSS_RESULT +obj_pcrs_get_digest_at_release(TSS_HPCRS hPcrs, UINT32 *size, BYTE **out) +{ + struct tsp_object *obj; + struct tr_pcrs_obj *pcrs; + TSS_RESULT result = TSS_SUCCESS; + BYTE *digest; + + if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + pcrs = (struct tr_pcrs_obj *)obj->data; + + switch(pcrs->type) { + case TSS_PCRS_STRUCT_INFO: + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + case TSS_PCRS_STRUCT_INFO_SHORT: + digest = (BYTE *)&pcrs->info.infoshort.digestAtRelease; + break; + case TSS_PCRS_STRUCT_INFO_LONG: + digest = (BYTE *)&pcrs->info.infolong.digestAtRelease; + break; + default: + LogDebugFn("Undefined type of PCRs object"); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + break; + } + + if ((*out = calloc_tspi(obj->tspContext, sizeof(TPM_COMPOSITE_HASH))) == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(TPM_COMPOSITE_HASH)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(*out, digest, sizeof(TPM_COMPOSITE_HASH)); + *size = sizeof(TPM_COMPOSITE_HASH); + +done: + obj_list_put(&pcrs_list); + + return result; +} + +TSS_RESULT +obj_pcrs_select_index(TSS_HPCRS hPcrs, UINT32 idx) +{ + struct tsp_object *obj; + struct tr_pcrs_obj *pcrs; + TSS_RESULT result = TSS_SUCCESS; + TPM_PCR_SELECTION *select; + UINT16 bytes_to_hold = (idx / 8) + 1; + + if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + pcrs = (struct tr_pcrs_obj *)obj->data; + + switch(pcrs->type) { + case TSS_PCRS_STRUCT_INFO: + bytes_to_hold = (bytes_to_hold < 2) ? 2 : bytes_to_hold; + select = &pcrs->info.info11.pcrSelection; + break; + case TSS_PCRS_STRUCT_INFO_SHORT: + case TSS_PCRS_STRUCT_INFO_LONG: + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + default: + LogDebugFn("Undefined type of PCRs object"); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + break; + } + + /* allocate the selection structure */ + if (select->pcrSelect == NULL) { + if ((select->pcrSelect = malloc(bytes_to_hold)) == NULL) { + LogError("malloc of %d bytes failed.", bytes_to_hold); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + select->sizeOfSelect = bytes_to_hold; + memset(select->pcrSelect, 0, bytes_to_hold); + + /* alloc the pcrs array */ + if ((pcrs->pcrs = malloc(bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN)) == NULL) { + LogError("malloc of %d bytes failed.", bytes_to_hold * 8 * + TCPA_SHA1_160_HASH_LEN); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + } else if (select->sizeOfSelect < bytes_to_hold) { + if ((select->pcrSelect = realloc(select->pcrSelect, bytes_to_hold)) == NULL) { + LogError("malloc of %d bytes failed.", bytes_to_hold); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + /* set the newly allocated bytes to 0 */ + memset(&select->pcrSelect[select->sizeOfSelect], 0, + bytes_to_hold - select->sizeOfSelect); + select->sizeOfSelect = bytes_to_hold; + + /* realloc the pcrs array */ + if ((pcrs->pcrs = realloc(pcrs->pcrs, + bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN)) == NULL) { + LogError("malloc of %d bytes failed.", bytes_to_hold * 8 * + TCPA_SHA1_160_HASH_LEN); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + } + + /* set the bit in the selection structure */ + select->pcrSelect[idx / 8] |= (1 << (idx % 8)); + +done: + obj_list_put(&pcrs_list); + + return result; +} + +TSS_RESULT +obj_pcrs_select_index_ex(TSS_HPCRS hPcrs, UINT32 dir, UINT32 idx) +{ + struct tsp_object *obj; + struct tr_pcrs_obj *pcrs; + TSS_RESULT result = TSS_SUCCESS; + TPM_PCR_SELECTION *select; + UINT16 bytes_to_hold = (idx / 8) + 1; + + if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + pcrs = (struct tr_pcrs_obj *)obj->data; + + switch(pcrs->type) { + case TSS_PCRS_STRUCT_INFO: + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + case TSS_PCRS_STRUCT_INFO_SHORT: + if (dir == TSS_PCRS_DIRECTION_CREATION) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + bytes_to_hold = (bytes_to_hold < 3) ? 3 : bytes_to_hold; + select = &pcrs->info.infoshort.pcrSelection; + break; + case TSS_PCRS_STRUCT_INFO_LONG: + bytes_to_hold = (bytes_to_hold < 3) ? 3 : bytes_to_hold; + if (dir == TSS_PCRS_DIRECTION_CREATION) + select = &pcrs->info.infolong.creationPCRSelection; + else + select = &pcrs->info.infolong.releasePCRSelection; + break; + default: + LogDebugFn("Undefined type of PCRs object"); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + break; + } + + /* allocate the selection structure */ + if (select->pcrSelect == NULL) { + if ((select->pcrSelect = malloc(bytes_to_hold)) == NULL) { + LogError("malloc of %d bytes failed.", bytes_to_hold); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + select->sizeOfSelect = bytes_to_hold; + memset(select->pcrSelect, 0, bytes_to_hold); + + /* alloc the pcrs array */ + if ((pcrs->pcrs = malloc(bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN)) == NULL) { + LogError("malloc of %d bytes failed.", bytes_to_hold * 8 * + TCPA_SHA1_160_HASH_LEN); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + } else if (select->sizeOfSelect < bytes_to_hold) { + if ((select->pcrSelect = realloc(select->pcrSelect, bytes_to_hold)) == NULL) { + LogError("malloc of %d bytes failed.", bytes_to_hold); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + /* set the newly allocated bytes to 0 */ + memset(&select->pcrSelect[select->sizeOfSelect], 0, + bytes_to_hold - select->sizeOfSelect); + select->sizeOfSelect = bytes_to_hold; + + /* realloc the pcrs array */ + if ((pcrs->pcrs = realloc(pcrs->pcrs, + bytes_to_hold * 8 * TCPA_SHA1_160_HASH_LEN)) == NULL) { + LogError("malloc of %d bytes failed.", bytes_to_hold * 8 * + TCPA_SHA1_160_HASH_LEN); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + } + + /* set the bit in the selection structure */ + select->pcrSelect[idx / 8] |= (1 << (idx % 8)); + +done: + obj_list_put(&pcrs_list); + + return result; +} + +TSS_RESULT +obj_pcrs_create_info_type(TSS_HPCRS hPcrs, UINT32 *type, UINT32 *size, BYTE **info) +{ + TSS_RESULT result; + + /* If type equals 0, then we create the structure + based on how the object was created */ + if (*type == 0) { + struct tsp_object *obj; + struct tr_pcrs_obj *pcrs; + + if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + pcrs = (struct tr_pcrs_obj *)obj->data; + *type = pcrs->type; + + obj_list_put(&pcrs_list); + } + + switch (*type) { + case TSS_PCRS_STRUCT_INFO: + result = obj_pcrs_create_info(hPcrs, size, info); + break; + case TSS_PCRS_STRUCT_INFO_LONG: + result = obj_pcrs_create_info_long(hPcrs, size, info); + break; + case TSS_PCRS_STRUCT_INFO_SHORT: + result = obj_pcrs_create_info_short(hPcrs, size, info); + break; + default: + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +/* Create a PCR info struct based on the hPcrs object */ +TSS_RESULT +obj_pcrs_create_info(TSS_HPCRS hPcrs, UINT32 *size, BYTE **info) +{ + struct tsp_object *obj; + struct tr_pcrs_obj *pcrs; + TSS_RESULT result = TSS_SUCCESS; + TPM_PCR_INFO info11; + UINT64 offset; + UINT32 ret_size; + BYTE *ret; + + if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + pcrs = (struct tr_pcrs_obj *)obj->data; + + /* Set everything that is not assigned to be all zeroes */ + memset(&info11, 0, sizeof(info11)); + + switch (pcrs->type) { + case TSS_PCRS_STRUCT_INFO: + info11 = pcrs->info.info11; + break; + case TSS_PCRS_STRUCT_INFO_LONG: + info11.pcrSelection = pcrs->info.infolong.releasePCRSelection; + info11.digestAtRelease = pcrs->info.infolong.digestAtRelease; + break; + case TSS_PCRS_STRUCT_INFO_SHORT: + info11.pcrSelection = pcrs->info.infoshort.pcrSelection; + info11.digestAtRelease = pcrs->info.infoshort.digestAtRelease; + break; + default: + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + offset = 0; + Trspi_LoadBlob_PCR_INFO(&offset, NULL, &info11); + ret_size = offset; + + if ((ret = calloc(1, ret_size)) == NULL) { + result = TSPERR(TSS_E_OUTOFMEMORY); + LogDebug("malloc of %u bytes failed.", ret_size); + goto done; + } + + offset = 0; + Trspi_LoadBlob_PCR_INFO(&offset, ret, &info11); + + *info = ret; + *size = ret_size; + +done: + obj_list_put(&pcrs_list); + + return result; +} + +TSS_RESULT +obj_pcrs_create_info_long(TSS_HPCRS hPcrs, UINT32 *size, BYTE **info) +{ + struct tsp_object *obj; + struct tr_pcrs_obj *pcrs; + TSS_RESULT result = TSS_SUCCESS; + TPM_PCR_INFO_LONG infolong; + BYTE dummyBits[3] = { 0, 0, 0 }; + TPM_PCR_SELECTION dummySelection = { 3, dummyBits }; + UINT64 offset; + UINT32 ret_size; + BYTE *ret; + + if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + pcrs = (struct tr_pcrs_obj *)obj->data; + + /* Set everything that is not assigned to be all zeroes */ + memset(&infolong, 0, sizeof(infolong)); + + infolong.tag = TPM_TAG_PCR_INFO_LONG; + /* localityAtCreation and creationPCRSelection certainly do not need to be set here, but + * some chips such as Winbond do not ignore them on input, so we must give them dummy + * "good" values */ + infolong.localityAtCreation = TPM_LOC_ZERO; + infolong.creationPCRSelection = dummySelection; + switch (pcrs->type) { + case TSS_PCRS_STRUCT_INFO: + infolong.localityAtRelease = TSS_LOCALITY_ALL; + infolong.releasePCRSelection = pcrs->info.info11.pcrSelection; + infolong.digestAtRelease = pcrs->info.info11.digestAtRelease; + break; + case TSS_PCRS_STRUCT_INFO_LONG: + infolong.localityAtRelease = pcrs->info.infolong.localityAtRelease; + infolong.releasePCRSelection = pcrs->info.infolong.releasePCRSelection; + infolong.digestAtRelease = pcrs->info.infolong.digestAtRelease; + break; + case TSS_PCRS_STRUCT_INFO_SHORT: + infolong.localityAtRelease = pcrs->info.infoshort.localityAtRelease; + infolong.releasePCRSelection = pcrs->info.infoshort.pcrSelection; + infolong.digestAtRelease = pcrs->info.infoshort.digestAtRelease; + break; + default: + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + offset = 0; + Trspi_LoadBlob_PCR_INFO_LONG(&offset, NULL, &infolong); + ret_size = offset; + + if ((ret = calloc(1, ret_size)) == NULL) { + result = TSPERR(TSS_E_OUTOFMEMORY); + LogDebug("malloc of %u bytes failed.", ret_size); + goto done; + } + + offset = 0; + Trspi_LoadBlob_PCR_INFO_LONG(&offset, ret, &infolong); + + *info = ret; + *size = ret_size; + +done: + obj_list_put(&pcrs_list); + + return result; +} + +TSS_RESULT +obj_pcrs_create_info_short(TSS_HPCRS hPcrs, UINT32 *size, BYTE **info) +{ + struct tsp_object *obj; + struct tr_pcrs_obj *pcrs; + TSS_RESULT result = TSS_SUCCESS; + TPM_PCR_INFO_SHORT infoshort; + BYTE select[] = { 0, 0, 0 }; + UINT64 offset; + UINT32 ret_size; + BYTE *ret; + + /* Set everything that is not assigned to be all zeroes */ + memset(&infoshort, 0, sizeof(infoshort)); + + if (hPcrs != NULL_HPCRS) { + if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + pcrs = (struct tr_pcrs_obj *)obj->data; + + switch (pcrs->type) { + case TSS_PCRS_STRUCT_INFO: + infoshort.pcrSelection = pcrs->info.info11.pcrSelection; + infoshort.localityAtRelease = TSS_LOCALITY_ALL; + infoshort.digestAtRelease = pcrs->info.info11.digestAtRelease; + break; + case TSS_PCRS_STRUCT_INFO_LONG: + infoshort.pcrSelection = pcrs->info.infolong.releasePCRSelection; + infoshort.localityAtRelease = pcrs->info.infolong.localityAtRelease; + infoshort.digestAtRelease = pcrs->info.infolong.digestAtRelease; + break; + case TSS_PCRS_STRUCT_INFO_SHORT: + infoshort = pcrs->info.infoshort; + break; + default: + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } else { + infoshort.pcrSelection.sizeOfSelect = sizeof(select); + infoshort.pcrSelection.pcrSelect = select; + infoshort.localityAtRelease = TSS_LOCALITY_ALL; + } + + offset = 0; + Trspi_LoadBlob_PCR_INFO_SHORT(&offset, NULL, &infoshort); + ret_size = offset; + + if ((ret = calloc(1, ret_size)) == NULL) { + result = TSPERR(TSS_E_OUTOFMEMORY); + LogDebug("malloc of %u bytes failed.", ret_size); + goto done; + } + + offset = 0; + Trspi_LoadBlob_PCR_INFO_SHORT(&offset, ret, &infoshort); + + *info = ret; + *size = ret_size; + +done: + if (hPcrs != NULL_HPCRS) + obj_list_put(&pcrs_list); + + return result; +} + +TSS_RESULT +obj_pcrs_get_locality(TSS_HPCRS hPcrs, UINT32 *out) +{ + struct tsp_object *obj; + struct tr_pcrs_obj *pcrs; + TSS_RESULT result = TSS_SUCCESS; + BYTE *locality; + + if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + pcrs = (struct tr_pcrs_obj *)obj->data; + + switch(pcrs->type) { + case TSS_PCRS_STRUCT_INFO: + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + case TSS_PCRS_STRUCT_INFO_SHORT: + locality = &pcrs->info.infoshort.localityAtRelease; + break; + case TSS_PCRS_STRUCT_INFO_LONG: + locality = &pcrs->info.infolong.localityAtRelease; + break; + default: + LogDebugFn("Undefined type of PCRs object"); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *out = (UINT32)*locality; + +done: + obj_list_put(&pcrs_list); + + return result; +} + +TSS_RESULT +obj_pcrs_set_locality(TSS_HPCRS hPcrs, UINT32 locality) +{ + struct tsp_object *obj; + struct tr_pcrs_obj *pcrs; + TSS_RESULT result = TSS_SUCCESS; + BYTE *loc; + + if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + pcrs = (struct tr_pcrs_obj *)obj->data; + + switch(pcrs->type) { + case TSS_PCRS_STRUCT_INFO: + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + case TSS_PCRS_STRUCT_INFO_SHORT: + loc = &pcrs->info.infoshort.localityAtRelease; + break; + case TSS_PCRS_STRUCT_INFO_LONG: + loc = &pcrs->info.infolong.localityAtRelease; + break; + default: + LogDebugFn("Undefined type of PCRs object"); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *loc = locality; +done: + obj_list_put(&pcrs_list); + + return result; +} + +TSS_RESULT +obj_pcrs_set_digest_at_release(TSS_HPCRS hPcrs, TPM_COMPOSITE_HASH digest) +{ + struct tsp_object *obj; + struct tr_pcrs_obj *pcrs; + TSS_RESULT result = TSS_SUCCESS; + TPM_COMPOSITE_HASH *dig; + + LogDebugFn("######## Digest to be set on TSS object:"); + LogDebugData(TCPA_SHA1_160_HASH_LEN, digest.digest); + + if ((obj = obj_list_get_obj(&pcrs_list, hPcrs)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + pcrs = (struct tr_pcrs_obj *)obj->data; + + switch(pcrs->type) { + case TSS_PCRS_STRUCT_INFO: + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + case TSS_PCRS_STRUCT_INFO_SHORT: + dig = &pcrs->info.infoshort.digestAtRelease; + break; + case TSS_PCRS_STRUCT_INFO_LONG: + dig = &pcrs->info.infolong.digestAtRelease; + break; + default: + LogDebugFn("Undefined type of PCRs object"); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + /* Copy the digest information */ + memcpy(dig->digest,&digest.digest,TPM_SHA1_160_HASH_LEN); + + LogDebugFn("######## Digest SET on TSS object:"); + LogDebugData(TCPA_SHA1_160_HASH_LEN,pcrs->info.infoshort.digestAtRelease.digest); + +done: + obj_list_put(&pcrs_list); + + return result; +} + diff --git a/src/tspi/obj_policy.c b/src/tspi/obj_policy.c new file mode 100644 index 0000000..e76681b --- /dev/null +++ b/src/tspi/obj_policy.c @@ -0,0 +1,1667 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2005, 2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" +#include "tsp_delegate.h" +#include "authsess.h" + + +TSS_RESULT +obj_policy_add(TSS_HCONTEXT tsp_context, UINT32 type, TSS_HOBJECT *phObject) +{ + struct tr_policy_obj *policy; + TSS_RESULT result; + + if ((policy = calloc(1, sizeof(struct tr_policy_obj))) == NULL) { + LogError("malloc of %zd bytes failed", sizeof(struct tr_policy_obj)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + policy->type = type; +#ifndef TSS_SPEC_COMPLIANCE + policy->SecretMode = TSS_SECRET_MODE_NONE; +#else + policy->SecretMode = TSS_SECRET_MODE_POPUP; +#endif + /* The policy object will inherit this attribute from the context */ + if ((result = obj_context_get_hash_mode(tsp_context, &policy->hashMode))) { + free(policy); + return result; + } + policy->SecretLifetime = TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS; +#ifdef TSS_BUILD_DELEGATION + policy->delegationType = TSS_DELEGATIONTYPE_NONE; +#endif + + if ((result = obj_list_add(&policy_list, tsp_context, 0, policy, phObject))) { + free(policy); + return result; + } + + return TSS_SUCCESS; +} + +void +__tspi_policy_free(void *data) +{ + struct tr_policy_obj *policy = (struct tr_policy_obj *)data; + + free(policy->popupString); +#ifdef TSS_BUILD_DELEGATION + free(policy->delegationBlob); +#endif + free(policy); +} + +TSS_RESULT +obj_policy_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext) +{ + TSS_RESULT result; + + if ((result = obj_list_remove(&policy_list, &__tspi_policy_free, hObject, tspContext))) + return result; + + obj_lists_remove_policy_refs(hObject, tspContext); + + return TSS_SUCCESS; +} + +TSS_BOOL +obj_is_policy(TSS_HOBJECT hObject) +{ + TSS_BOOL answer = FALSE; + + if ((obj_list_get_obj(&policy_list, hObject))) { + answer = TRUE; + obj_list_put(&policy_list); + } + + return answer; +} + +TSS_RESULT +obj_policy_get_type(TSS_HPOLICY hPolicy, UINT32 *type) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + *type = policy->type; + + obj_list_put(&policy_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_policy_set_type(TSS_HPOLICY hPolicy, UINT32 type) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + policy->type = type; + + obj_list_put(&policy_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_policy_get_tsp_context(TSS_HPOLICY hPolicy, TSS_HCONTEXT *tspContext) +{ + struct tsp_object *obj; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + *tspContext = obj->tspContext; + + obj_list_put(&policy_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_policy_do_hmac(TSS_HPOLICY hPolicy, TSS_HOBJECT hAuthorizedObject, + TSS_BOOL returnOrVerify, UINT32 ulPendingFunction, + TSS_BOOL continueUse, UINT32 ulSizeNonces, + BYTE *rgbNonceEven, BYTE *rgbNonceOdd, + BYTE *rgbNonceEvenOSAP, BYTE *rgbNonceOddOSAP, + UINT32 ulSizeDigestHmac, BYTE *rgbParamDigest, + BYTE *rgbHmacData) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + result = policy->Tspicb_CallbackHMACAuth( + policy->hmacAppData, hAuthorizedObject, + returnOrVerify, + ulPendingFunction, + continueUse, + ulSizeNonces, + rgbNonceEven, + rgbNonceOdd, + rgbNonceEvenOSAP, rgbNonceOddOSAP, ulSizeDigestHmac, + rgbParamDigest, + rgbHmacData); + + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_get_secret(TSS_HPOLICY hPolicy, TSS_BOOL ctx, TCPA_SECRET *secret) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TSS_RESULT result = TSS_SUCCESS; + TCPA_SECRET null_secret; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + memset(&null_secret, 0, sizeof(TCPA_SECRET)); + + switch (policy->SecretMode) { + case TSS_SECRET_MODE_POPUP: + /* if the secret is still NULL, grab it using the GUI */ + if (policy->SecretSet == FALSE) { + if ((result = popup_GetSecret(ctx, + policy->hashMode, + policy->popupString, + policy->Secret))) + break; + } + policy->SecretSet = TRUE; + /* fall through */ + case TSS_SECRET_MODE_PLAIN: + case TSS_SECRET_MODE_SHA1: + if (policy->SecretSet == FALSE) { + result = TSPERR(TSS_E_POLICY_NO_SECRET); + break; + } + + memcpy(secret, policy->Secret, sizeof(TCPA_SECRET)); + break; + case TSS_SECRET_MODE_NONE: + memcpy(secret, &null_secret, sizeof(TCPA_SECRET)); + break; + default: + result = TSPERR(TSS_E_POLICY_NO_SECRET); + break; + } +#ifdef TSS_DEBUG + if (!result) { + LogDebug("Got a secret:"); + LogDebugData(20, (BYTE *)secret); + } +#endif + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_flush_secret(TSS_HPOLICY hPolicy) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + memset(&policy->Secret, 0, policy->SecretSize); + policy->SecretSet = FALSE; + + obj_list_put(&policy_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_policy_set_secret_object(TSS_HPOLICY hPolicy, TSS_FLAG mode, UINT32 size, + TCPA_DIGEST *digest, TSS_BOOL set) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + /* if this is going to be a callback policy, the + * callbacks need to already be set. (See TSS 1.1b + * spec pg. 62). */ + if (mode == TSS_SECRET_MODE_CALLBACK) { + if (policy->Tspicb_CallbackHMACAuth == NULL) { + result = TSPERR(TSS_E_FAIL); + goto done; + } + } + + if (policy->SecretLifetime == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER) { + policy->SecretCounter = policy->SecretTimeStamp; + } else if (policy->SecretLifetime == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER) { + time_t t = time(NULL); + if (t == ((time_t)-1)) { + LogError("time failed: %s", strerror(errno)); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + policy->SecretTimeStamp = t; + } + + memcpy(policy->Secret, digest, size); + policy->SecretMode = mode; + policy->SecretSize = size; + policy->SecretSet = set; +done: + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_is_secret_set(TSS_HPOLICY hPolicy, TSS_BOOL *secretSet) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + *secretSet = policy->SecretSet; + obj_list_put(&policy_list); + + return result; +} + + +TSS_RESULT +obj_policy_set_secret(TSS_HPOLICY hPolicy, TSS_FLAG mode, UINT32 size, BYTE *data) +{ + TCPA_DIGEST digest; + UINT32 secret_size = 0; + TSS_BOOL secret_set = TRUE; + TSS_RESULT result; + + memset(&digest.digest, 0, sizeof(TCPA_DIGEST)); + + switch (mode) { + case TSS_SECRET_MODE_PLAIN: + if ((result = Trspi_Hash(TSS_HASH_SHA1, size, data, + (BYTE *)&digest.digest))) + return result; + secret_size = TCPA_SHA1_160_HASH_LEN; + break; + case TSS_SECRET_MODE_SHA1: + if (size != TCPA_SHA1_160_HASH_LEN) + return TSPERR(TSS_E_BAD_PARAMETER); + + memcpy(&digest.digest, data, size); + secret_size = TCPA_SHA1_160_HASH_LEN; + break; + case TSS_SECRET_MODE_POPUP: + case TSS_SECRET_MODE_NONE: + secret_set = FALSE; + case TSS_SECRET_MODE_CALLBACK: + break; + default: + return TSPERR(TSS_E_BAD_PARAMETER); + } + + return obj_policy_set_secret_object(hPolicy, mode, secret_size, + &digest, secret_set); +} + +TSS_RESULT +obj_policy_get_cb11(TSS_HPOLICY hPolicy, TSS_FLAG type, UINT32 *cb) +{ +#ifndef __LP64__ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + switch (type) { + case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC: + *cb = (UINT32)policy->Tspicb_CallbackHMACAuth; + break; + case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC: + *cb = (UINT32)policy->Tspicb_CallbackXorEnc; + break; + case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP: + *cb = (UINT32)policy->Tspicb_CallbackTakeOwnership; + break; + case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM: + *cb = (UINT32)policy->Tspicb_CallbackChangeAuthAsym; + break; + default: + result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } + + obj_list_put(&policy_list); + + return result; +#else + return TSPERR(TSS_E_FAIL); +#endif +} + +TSS_RESULT +obj_policy_set_cb11(TSS_HPOLICY hPolicy, TSS_FLAG type, TSS_FLAG app_data, UINT32 cb) +{ +#ifndef __LP64__ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + switch (type) { + case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC: + policy->Tspicb_CallbackHMACAuth = (PVOID)cb; + policy->hmacAppData = (PVOID)app_data; + break; + case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC: + policy->Tspicb_CallbackXorEnc = (PVOID)cb; + policy->xorAppData = (PVOID)app_data; + break; + case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP: + policy->Tspicb_CallbackTakeOwnership = (PVOID)cb; + policy->takeownerAppData = (PVOID)app_data; + break; + case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM: + policy->Tspicb_CallbackChangeAuthAsym = (PVOID)cb; + policy->changeauthAppData = (PVOID)app_data; + break; + default: + result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } + + obj_list_put(&policy_list); + + return result; +#else + return TSPERR(TSS_E_FAIL); +#endif +} + +TSS_RESULT +obj_policy_set_cb12(TSS_HPOLICY hPolicy, TSS_FLAG flag, BYTE *in) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TSS_RESULT result = TSS_SUCCESS; + TSS_CALLBACK *cb = (TSS_CALLBACK *)in; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + switch (flag) { + case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC: + if (!cb) { + policy->Tspicb_CallbackHMACAuth = NULL; + break; + } + + policy->Tspicb_CallbackHMACAuth = + (TSS_RESULT (*)(PVOID, TSS_HOBJECT, TSS_BOOL, + UINT32, TSS_BOOL, UINT32, BYTE *, BYTE *, + BYTE *, BYTE *, UINT32, BYTE *, BYTE *)) + cb->callback; + policy->hmacAppData = cb->appData; + policy->hmacAlg = cb->alg; + break; + case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC: + if (!cb) { + policy->Tspicb_CallbackXorEnc = NULL; + break; + } + + policy->Tspicb_CallbackXorEnc = + (TSS_RESULT (*)(PVOID, TSS_HOBJECT, + TSS_HOBJECT, TSS_FLAG, UINT32, BYTE *, BYTE *, + BYTE *, BYTE *, UINT32, BYTE *, BYTE *)) + cb->callback; + policy->xorAppData = cb->appData; + policy->xorAlg = cb->alg; + break; + case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP: + if (!cb) { + policy->Tspicb_CallbackTakeOwnership = NULL; + break; + } + + policy->Tspicb_CallbackTakeOwnership = + (TSS_RESULT (*)(PVOID, TSS_HOBJECT, TSS_HKEY, + UINT32, BYTE *))cb->callback; + policy->takeownerAppData = cb->appData; + policy->takeownerAlg = cb->alg; + break; + case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM: + if (!cb) { + policy->Tspicb_CallbackChangeAuthAsym = NULL; + break; + } + + policy->Tspicb_CallbackChangeAuthAsym = + (TSS_RESULT (*)(PVOID, TSS_HOBJECT, TSS_HKEY, + UINT32, UINT32, BYTE *, BYTE *))cb->callback; + policy->changeauthAppData = cb->appData; + policy->changeauthAlg = cb->alg; + break; +#ifdef TSS_BUILD_SEALX + case TSS_TSPATTRIB_POLICY_CALLBACK_SEALX_MASK: + if (!cb) { + policy->Tspicb_CallbackSealxMask = NULL; + policy->sealxAppData = NULL; + policy->sealxAlg = 0; + break; + } + + policy->Tspicb_CallbackSealxMask = + (TSS_RESULT (*)(PVOID, TSS_HKEY, TSS_HENCDATA, + TSS_ALGORITHM_ID, UINT32, BYTE *, BYTE *, BYTE *, BYTE *, + UINT32, BYTE *, BYTE *))cb->callback; + policy->sealxAppData = cb->appData; + policy->sealxAlg = cb->alg; + break; +#endif + default: + result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } + + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_get_cb12(TSS_HPOLICY hPolicy, TSS_FLAG flag, UINT32 *size, BYTE **out) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TSS_RESULT result = TSS_SUCCESS; + TSS_CALLBACK *cb; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + if ((cb = calloc_tspi(obj->tspContext, sizeof(TSS_CALLBACK))) == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(TSS_CALLBACK)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + switch (flag) { + case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC: + cb->callback = policy->Tspicb_CallbackHMACAuth; + cb->appData = policy->hmacAppData; + cb->alg = policy->hmacAlg; + *size = sizeof(TSS_CALLBACK); + *out = (BYTE *)cb; + break; + case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC: + cb->callback = policy->Tspicb_CallbackXorEnc; + cb->appData = policy->xorAppData; + cb->alg = policy->xorAlg; + *size = sizeof(TSS_CALLBACK); + *out = (BYTE *)cb; + break; + case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP: + cb->callback = policy->Tspicb_CallbackTakeOwnership; + cb->appData = policy->takeownerAppData; + cb->alg = policy->takeownerAlg; + *size = sizeof(TSS_CALLBACK); + *out = (BYTE *)cb; + break; + case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM: + cb->callback = policy->Tspicb_CallbackChangeAuthAsym; + cb->appData = policy->changeauthAppData; + cb->alg = policy->changeauthAlg; + *size = sizeof(TSS_CALLBACK); + *out = (BYTE *)cb; + break; +#ifdef TSS_BUILD_SEALX + case TSS_TSPATTRIB_POLICY_CALLBACK_SEALX_MASK: + cb->callback = policy->Tspicb_CallbackSealxMask; + cb->appData = policy->sealxAppData; + cb->alg = policy->sealxAlg; + *size = sizeof(TSS_CALLBACK); + *out = (BYTE *)cb; + break; +#endif + default: + free_tspi(obj->tspContext, cb); + result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } +done: + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_get_lifetime(TSS_HPOLICY hPolicy, UINT32 *lifetime) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + *lifetime = policy->SecretLifetime; + + obj_list_put(&policy_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_policy_set_lifetime(TSS_HPOLICY hPolicy, UINT32 type, UINT32 value) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TSS_RESULT result = TSS_SUCCESS; + time_t t; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + switch (type) { + case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS: + policy->SecretCounter = 0; + policy->SecretLifetime = TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS; + policy->SecretTimeStamp = 0; + break; + case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER: + /* Both SecretCounter and SecretTimeStamp will receive value. Every time the + * policy is used, SecretCounter will be decremented. Each time SetSecret is + * called, SecretCounter will get the value stored in SecretTimeStamp */ + policy->SecretCounter = value; + policy->SecretLifetime = TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER; + policy->SecretTimeStamp = value; + break; + case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER: + t = time(NULL); + if (t == ((time_t)-1)) { + LogError("time failed: %s", strerror(errno)); + result = TSPERR(TSS_E_INTERNAL_ERROR); + break; + } + + /* For mode time, we'll use the SecretCounter variable to hold the number + * of seconds we're valid and the SecretTimeStamp var to record the current + * timestamp. This should protect against overflows. */ + policy->SecretCounter = value; + policy->SecretLifetime = TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER; + policy->SecretTimeStamp = t; + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + break; + } + + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_get_mode(TSS_HPOLICY hPolicy, UINT32 *mode) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + *mode = policy->SecretMode; + + obj_list_put(&policy_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_policy_get_counter(TSS_HPOLICY hPolicy, UINT32 *counter) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + if (policy->SecretLifetime == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER) + *counter = policy->SecretCounter; + else + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_dec_counter(TSS_HPOLICY hPolicy) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + /* Only decrement if SecretCounter > 0, otherwise it could loop and become valid again */ + if (policy->SecretLifetime == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER && + policy->SecretCounter > 0) { + policy->SecretCounter--; + } + + obj_list_put(&policy_list); + + return TSS_SUCCESS; +} + +/* return a unicode string to the Tspi_GetAttribData function */ +TSS_RESULT +obj_policy_get_string(TSS_HPOLICY hPolicy, UINT32 *size, BYTE **data) +{ + TSS_RESULT result = TSS_SUCCESS; + BYTE *utf_string; + UINT32 utf_size; + struct tsp_object *obj; + struct tr_policy_obj *policy; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + *size = policy->popupStringLength; + if (policy->popupStringLength == 0) { + *data = NULL; + } else { + utf_size = policy->popupStringLength; + utf_string = Trspi_Native_To_UNICODE(policy->popupString, + &utf_size); + if (utf_string == NULL) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *data = calloc_tspi(obj->tspContext, utf_size); + if (*data == NULL) { + free(utf_string); + LogError("malloc of %d bytes failed.", utf_size); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + *size = utf_size; + memcpy(*data, utf_string, utf_size); + free(utf_string); + } + +done: + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_set_string(TSS_HPOLICY hPolicy, UINT32 size, BYTE *data) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + free(policy->popupString); + policy->popupString = data; + policy->popupStringLength = size; + + obj_list_put(&policy_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_policy_get_secs_until_expired(TSS_HPOLICY hPolicy, UINT32 *secs) +{ + TSS_RESULT result = TSS_SUCCESS; + struct tsp_object *obj; + struct tr_policy_obj *policy; + int seconds_elapsed; + time_t t; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + if (policy->SecretLifetime != TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + if ((t = time(NULL)) == ((time_t)-1)) { + LogError("time failed: %s", strerror(errno)); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + /* curtime - SecretTimeStamp is the number of seconds elapsed since we started the timer. + * SecretCounter is the number of seconds the secret is valid. If + * seconds_elspased > SecretCounter, we've expired. */ + seconds_elapsed = t - policy->SecretTimeStamp; + if ((UINT32)seconds_elapsed >= policy->SecretCounter) { + *secs = 0; + } else { + *secs = policy->SecretCounter - seconds_elapsed; + } + +done: + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +policy_has_expired(struct tr_policy_obj *policy, TSS_BOOL *answer) +{ + switch (policy->SecretLifetime) { + case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS: + *answer = FALSE; + break; + case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER: + *answer = (policy->SecretCounter == 0 ? TRUE : FALSE); + break; + case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER: + { + int seconds_elapsed; + time_t t = time(NULL); + + if (t == ((time_t)-1)) { + LogError("time failed: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + /* curtime - SecretTimer is the number of seconds elapsed since we + * started the timer. SecretCounter is the number of seconds the + * secret is valid. If seconds_elspased > SecretCounter, we've + * expired. + */ + seconds_elapsed = t - policy->SecretTimeStamp; + *answer = ((UINT32)seconds_elapsed >= policy->SecretCounter ? TRUE : FALSE); + break; + } + default: + LogError("policy has an undefined secret lifetime!"); + return TSPERR(TSS_E_INVALID_OBJ_ACCESS); + } + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_policy_has_expired(TSS_HPOLICY hPolicy, TSS_BOOL *answer) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TSS_RESULT result; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + result = policy_has_expired(policy, answer); + + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_get_xsap_params(TSS_HPOLICY hPolicy, + TPM_COMMAND_CODE command, + TPM_ENTITY_TYPE *et, + UINT32 *entity_value_size, + BYTE **entity_value, + BYTE *secret, + TSS_CALLBACK *cb_xor, + TSS_CALLBACK *cb_hmac, + TSS_CALLBACK *cb_sealx, + UINT32 *mode, + TSS_BOOL new_secret) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TSS_RESULT result; + TSS_BOOL answer = FALSE; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + if ((result = policy_has_expired(policy, &answer))) + goto done; + + if (answer) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } +#ifdef TSS_BUILD_DELEGATION + /* if the delegation index or blob is set, check to see if the command is delegated, if so, + * return the blob or index as the secret data */ + if (command && (policy->delegationType != TSS_DELEGATIONTYPE_NONE)) { + if (policy->delegationBlob) { + if ((*entity_value = malloc(policy->delegationBlobLength)) == NULL) { + LogError("malloc of %u bytes failed.", + policy->delegationBlobLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + memcpy(*entity_value, policy->delegationBlob, policy->delegationBlobLength); + *entity_value_size = policy->delegationBlobLength; + if (policy->delegationType == TSS_DELEGATIONTYPE_OWNER) + *et = TPM_ET_DEL_OWNER_BLOB; + else + *et = TPM_ET_DEL_KEY_BLOB; + } else { + if ((*entity_value = malloc(sizeof(UINT32))) == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(UINT32)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + *(UINT32 *)entity_value = policy->delegationIndex; + *entity_value_size = sizeof(UINT32); + *et = TPM_ET_DEL_ROW; + } + } +#endif + /* Either this is a policy set to mode callback, in which case both xor and hmac addresses + * must be set, or this is an encrypted data object's policy, where its mode is independent + * of whether a sealx callback is set */ + if (policy->SecretMode == TSS_SECRET_MODE_CALLBACK && cb_xor && cb_hmac) { + if ((policy->Tspicb_CallbackXorEnc && !policy->Tspicb_CallbackHMACAuth) || + (!policy->Tspicb_CallbackXorEnc && policy->Tspicb_CallbackHMACAuth)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + cb_xor->callback = policy->Tspicb_CallbackXorEnc; + cb_xor->appData = policy->xorAppData; + cb_xor->alg = policy->xorAlg; + + cb_hmac->callback = policy->Tspicb_CallbackHMACAuth; + cb_hmac->appData = policy->hmacAppData; + cb_hmac->alg = policy->hmacAlg; +#ifdef TSS_BUILD_SEALX + } else if (cb_sealx && policy->Tspicb_CallbackSealxMask) { + cb_sealx->callback = policy->Tspicb_CallbackSealxMask; + cb_sealx->appData = policy->sealxAppData; + cb_sealx->alg = policy->sealxAlg; +#endif + } + + if ((policy->SecretMode == TSS_SECRET_MODE_POPUP) && + (policy->SecretSet == FALSE)) { + if ((result = popup_GetSecret(new_secret, + policy->hashMode, + policy->popupString, + policy->Secret))) + goto done; + policy->SecretSet = TRUE; + } + memcpy(secret, policy->Secret, TPM_SHA1_160_HASH_LEN); + *mode = policy->SecretMode; +done: + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_do_xor(TSS_HPOLICY hPolicy, + TSS_HOBJECT hOSAPObject, TSS_HOBJECT hObject, + TSS_FLAG PurposeSecret, UINT32 ulSizeNonces, + BYTE *rgbNonceEven, BYTE *rgbNonceOdd, + BYTE *rgbNonceEvenOSAP, BYTE *rgbNonceOddOSAP, + UINT32 ulSizeEncAuth, BYTE *rgbEncAuthUsage, + BYTE *rgbEncAuthMigration) +{ + TSS_RESULT result; + struct tsp_object *obj; + struct tr_policy_obj *policy; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + result = policy->Tspicb_CallbackXorEnc(policy->xorAppData, + hOSAPObject, hObject, + PurposeSecret, ulSizeNonces, + rgbNonceEven, rgbNonceOdd, + rgbNonceEvenOSAP, rgbNonceOddOSAP, + ulSizeEncAuth, + rgbEncAuthUsage, rgbEncAuthMigration); + + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_do_takeowner(TSS_HPOLICY hPolicy, + TSS_HOBJECT hObject, TSS_HKEY hObjectPubKey, + UINT32 ulSizeEncAuth, BYTE *rgbEncAuth) +{ + TSS_RESULT result; + struct tsp_object *obj; + struct tr_policy_obj *policy; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + result = policy->Tspicb_CallbackTakeOwnership( + policy->takeownerAppData, + hObject, hObjectPubKey, ulSizeEncAuth, + rgbEncAuth); + + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_get_hash_mode(TSS_HPOLICY hPolicy, UINT32 *mode) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + *mode = policy->hashMode; + + obj_list_put(&policy_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_policy_set_hash_mode(TSS_HPOLICY hPolicy, UINT32 mode) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + + switch (mode) { + case TSS_TSPATTRIB_HASH_MODE_NULL: + case TSS_TSPATTRIB_HASH_MODE_NOT_NULL: + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_DATA); + } + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + policy->hashMode = mode; + + obj_list_put(&policy_list); + + return TSS_SUCCESS; +} + +#ifdef TSS_BUILD_DELEGATION +TSS_RESULT +obj_policy_set_delegation_type(TSS_HPOLICY hPolicy, UINT32 type) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + switch (type) { + case TSS_DELEGATIONTYPE_NONE: + obj_policy_clear_delegation(policy); + break; + case TSS_DELEGATIONTYPE_OWNER: + case TSS_DELEGATIONTYPE_KEY: + if (policy->delegationIndexSet || policy->delegationBlob) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + break; + } + + policy->delegationType = type; + +done: + obj_list_put(&policy_list); + + return result; +} + + +TSS_RESULT +obj_policy_get_delegation_type(TSS_HPOLICY hPolicy, UINT32 *type) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + *type = policy->delegationType; + + obj_list_put(&policy_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_policy_set_delegation_index(TSS_HPOLICY hPolicy, UINT32 index) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TPM_DELEGATE_PUBLIC public; + TSS_RESULT result; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + if ((result = get_delegate_index(obj->tspContext, index, &public))) + goto done; + + free(public.pcrInfo.pcrSelection.pcrSelect); + + obj_policy_clear_delegation(policy); + switch (public.permissions.delegateType) { + case TPM_DEL_OWNER_BITS: + policy->delegationType = TSS_DELEGATIONTYPE_OWNER; + break; + case TPM_DEL_KEY_BITS: + policy->delegationType = TSS_DELEGATIONTYPE_KEY; + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + policy->delegationIndex = index; + policy->delegationIndexSet = TRUE; + +done: + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_get_delegation_index(TSS_HPOLICY hPolicy, UINT32 *index) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + if (!policy->delegationIndexSet) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + *index = policy->delegationIndex; + +done: + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT obj_policy_set_delegation_per1(TSS_HPOLICY hPolicy, UINT32 per1) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + if (policy->delegationIndexSet || policy->delegationBlob) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + policy->delegationPer1 = per1; + +done: + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT obj_policy_get_delegation_per1(TSS_HPOLICY hPolicy, UINT32 *per1) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TPM_DELEGATE_PUBLIC public; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + if (policy->delegationIndexSet || policy->delegationBlob) { + if ((result = obj_policy_get_delegate_public(obj, &public))) + goto done; + *per1 = public.permissions.per1; + free(public.pcrInfo.pcrSelection.pcrSelect); + } else + *per1 = policy->delegationPer1; + +done: + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT obj_policy_set_delegation_per2(TSS_HPOLICY hPolicy, UINT32 per2) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + if (policy->delegationIndexSet || policy->delegationBlob) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + policy->delegationPer2 = per2; + +done: + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT obj_policy_get_delegation_per2(TSS_HPOLICY hPolicy, UINT32 *per2) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TPM_DELEGATE_PUBLIC public; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + if (policy->delegationIndexSet || policy->delegationBlob) { + if ((result = obj_policy_get_delegate_public(obj, &public))) + goto done; + *per2 = public.permissions.per2; + free(public.pcrInfo.pcrSelection.pcrSelect); + } else + *per2 = policy->delegationPer2; + +done: + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_set_delegation_blob(TSS_HPOLICY hPolicy, UINT32 type, UINT32 blobLength, BYTE *blob) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + UINT16 tag; + UINT64 offset; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + obj_policy_clear_delegation(policy); + + if (blobLength == 0) { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + + offset = 0; + Trspi_UnloadBlob_UINT16(&offset, &tag, blob); + switch (tag) { + case TPM_TAG_DELEGATE_OWNER_BLOB: + if (type && (type != TSS_DELEGATIONTYPE_OWNER)) { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + policy->delegationType = TSS_DELEGATIONTYPE_OWNER; + break; + case TPM_TAG_DELG_KEY_BLOB: + if (type && (type != TSS_DELEGATIONTYPE_KEY)) { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + policy->delegationType = TSS_DELEGATIONTYPE_KEY; + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + + if ((policy->delegationBlob = malloc(blobLength)) == NULL) { + LogError("malloc of %u bytes failed.", blobLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + policy->delegationBlobLength = blobLength; + memcpy(policy->delegationBlob, blob, blobLength); + +done: + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_get_delegation_blob(TSS_HPOLICY hPolicy, UINT32 type, UINT32 *blobLength, BYTE **blob) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + if (policy->delegationBlobLength == 0) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + if (type && (type != policy->delegationType)) { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + + if ((*blob = calloc_tspi(obj->tspContext, policy->delegationBlobLength)) == NULL) { + LogError("malloc of %u bytes failed.", policy->delegationBlobLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + memcpy(*blob, policy->delegationBlob, policy->delegationBlobLength); + *blobLength = policy->delegationBlobLength; + +done: + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_get_delegation_label(TSS_HPOLICY hPolicy, BYTE *label) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TPM_DELEGATE_PUBLIC public; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + if (policy->delegationIndexSet || policy->delegationBlob) { + if ((result = obj_policy_get_delegate_public(obj, &public))) + goto done; + *label = public.label.label; + free(public.pcrInfo.pcrSelection.pcrSelect); + } else + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + +done: + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_get_delegation_familyid(TSS_HPOLICY hPolicy, UINT32 *familyID) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TPM_DELEGATE_PUBLIC public; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + if (policy->delegationIndexSet || policy->delegationBlob) { + if ((result = obj_policy_get_delegate_public(obj, &public))) + goto done; + *familyID = public.familyID; + free(public.pcrInfo.pcrSelection.pcrSelect); + } else + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + +done: + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_get_delegation_vercount(TSS_HPOLICY hPolicy, UINT32 *verCount) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TPM_DELEGATE_PUBLIC public; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + if (policy->delegationIndexSet || policy->delegationBlob) { + if ((result = obj_policy_get_delegate_public(obj, &public))) + goto done; + *verCount = public.verificationCount; + free(public.pcrInfo.pcrSelection.pcrSelect); + } else + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + +done: + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_get_delegation_pcr_locality(TSS_HPOLICY hPolicy, UINT32 *locality) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TPM_DELEGATE_PUBLIC public; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + if (policy->delegationIndexSet || policy->delegationBlob) { + if ((result = obj_policy_get_delegate_public(obj, &public))) + goto done; + *locality = public.pcrInfo.localityAtRelease; + free(public.pcrInfo.pcrSelection.pcrSelect); + } else + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + +done: + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_get_delegation_pcr_digest(TSS_HPOLICY hPolicy, UINT32 *digestLength, BYTE **digest) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TPM_DELEGATE_PUBLIC public; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + if (policy->delegationIndexSet || policy->delegationBlob) { + if ((result = obj_policy_get_delegate_public(obj, &public))) + goto done; + *digest = calloc_tspi(obj->tspContext, TPM_SHA1_160_HASH_LEN); + if (*digest == NULL) { + LogError("malloc of %u bytes failed.", TPM_SHA1_160_HASH_LEN); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(*digest, &public.pcrInfo.digestAtRelease.digest, TPM_SHA1_160_HASH_LEN); + *digestLength = TPM_SHA1_160_HASH_LEN; + free(public.pcrInfo.pcrSelection.pcrSelect); + } else + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + +done: + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_get_delegation_pcr_selection(TSS_HPOLICY hPolicy, UINT32 *selectionLength, + BYTE **selection) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + TPM_DELEGATE_PUBLIC public; + UINT64 offset; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + if (policy->delegationIndexSet || policy->delegationBlob) { + if ((result = obj_policy_get_delegate_public(obj, &public))) + goto done; + offset = 0; + Trspi_LoadBlob_PCR_SELECTION(&offset, NULL, &public.pcrInfo.pcrSelection); + *selection = calloc_tspi(obj->tspContext, offset); + if (*selection == NULL) { + LogError("malloc of %u bytes failed.", (UINT32)offset); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + offset = 0; + Trspi_LoadBlob_PCR_SELECTION(&offset, *selection, &public.pcrInfo.pcrSelection); + *selectionLength = offset; + free(public.pcrInfo.pcrSelection.pcrSelect); + } else + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + +done: + obj_list_put(&policy_list); + + return result; +} + +TSS_RESULT +obj_policy_is_delegation_index_set(TSS_HPOLICY hPolicy, TSS_BOOL *indexSet) +{ + struct tsp_object *obj; + struct tr_policy_obj *policy; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + *indexSet = policy->delegationIndexSet; + + obj_list_put(&policy_list); + + return TSS_SUCCESS; +} + +void +obj_policy_clear_delegation(struct tr_policy_obj *policy) +{ + free(policy->delegationBlob); + policy->delegationType = TSS_DELEGATIONTYPE_NONE; + policy->delegationPer1 = 0; + policy->delegationPer2 = 0; + policy->delegationIndexSet = FALSE; + policy->delegationIndex = 0; + policy->delegationBlobLength = 0; + policy->delegationBlob = NULL; +} + +TSS_RESULT +obj_policy_get_delegate_public(struct tsp_object *obj, TPM_DELEGATE_PUBLIC *public) +{ + struct tr_policy_obj *policy; + UINT16 tag; + TPM_DELEGATE_OWNER_BLOB ownerBlob; + TPM_DELEGATE_KEY_BLOB keyBlob; + UINT64 offset; + TSS_RESULT result; + + policy = (struct tr_policy_obj *)obj->data; + + if (policy->delegationIndexSet) { + if ((result = get_delegate_index(obj->tspContext, policy->delegationIndex, + public))) + return result; + } else if (policy->delegationBlob) { + offset = 0; + Trspi_UnloadBlob_UINT16(&offset, &tag, policy->delegationBlob); + + offset = 0; + switch (tag) { + case TPM_TAG_DELEGATE_OWNER_BLOB: + if ((result = Trspi_UnloadBlob_TPM_DELEGATE_OWNER_BLOB(&offset, + policy->delegationBlob, + &ownerBlob))) + return result; + *public = ownerBlob.pub; + free(ownerBlob.additionalArea); + free(ownerBlob.sensitiveArea); + break; + case TPM_TAG_DELG_KEY_BLOB: + if ((result = Trspi_UnloadBlob_TPM_DELEGATE_KEY_BLOB(&offset, + policy->delegationBlob, + &keyBlob))) + return result; + *public = keyBlob.pub; + free(keyBlob.additionalArea); + free(keyBlob.sensitiveArea); + break; + default: + return TSPERR(TSS_E_INTERNAL_ERROR); + } + } else + return TSPERR(TSS_E_INTERNAL_ERROR); + + return TSS_SUCCESS; +} +#endif + diff --git a/src/tspi/obj_rsakey.c b/src/tspi/obj_rsakey.c new file mode 100644 index 0000000..3f509f1 --- /dev/null +++ b/src/tspi/obj_rsakey.c @@ -0,0 +1,2136 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2005, 2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + +TSS_RESULT +obj_rsakey_add(TSS_HCONTEXT tspContext, TSS_FLAG initFlags, TSS_HOBJECT *phObject) +{ + UINT64 offset; + TSS_RESULT result; + TCPA_RSA_KEY_PARMS rsaKeyParms; + TSS_FLAG flags = 0; + struct tr_rsakey_obj *rsakey = calloc(1, sizeof(struct tr_rsakey_obj)); + TPM_STRUCT_VER ver = { 1, 1, 0, 0 }; // Must be 1.1.0.0 for 1.2 TPMs + UINT32 ctx_ver; + + if (rsakey == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(struct tr_rsakey_obj)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + if ((result = obj_context_get_policy(tspContext, TSS_POLICY_USAGE, &rsakey->usagePolicy))) { + free(rsakey); + return result; + } + + if ((initFlags & TSS_KEY_STRUCT_BITMASK) == TSS_KEY_STRUCT_DEFAULT) { + /* Its not set, go with the context's default */ + if ((result = obj_context_get_connection_version(tspContext, &ctx_ver))) { + free(rsakey); + return result; + } + + switch (ctx_ver) { + case TSS_TSPATTRIB_CONTEXT_VERSION_V1_2: + initFlags |= TSS_KEY_STRUCT_KEY12; + break; + case TSS_TSPATTRIB_CONTEXT_VERSION_V1_1: + /* fall through */ + default: + initFlags |= TSS_KEY_STRUCT_KEY; + break; + } + } + + offset = 0; + switch (initFlags & TSS_KEY_STRUCT_BITMASK) { + case TSS_KEY_STRUCT_KEY: + rsakey->key.hdr.key11.ver = ver; + rsakey->type = TSS_KEY_STRUCT_KEY; + rsakey->pcrInfoType = TSS_PCRS_STRUCT_INFO; + rsakey->key.keyFlags = 0; + break; + case TSS_KEY_STRUCT_KEY12: + rsakey->key.hdr.key12.tag = TPM_TAG_KEY12; + rsakey->key.hdr.key12.fill = 0; + rsakey->type = TSS_KEY_STRUCT_KEY12; + rsakey->pcrInfoType = TSS_PCRS_STRUCT_INFO_LONG; + rsakey->key.keyFlags = TPM_PCRIGNOREDONREAD; + break; + default: + free(rsakey); + return TSPERR(TSS_E_INVALID_OBJECT_INITFLAG); + break; + } + + if (initFlags == TSS_KEY_EMPTY_KEY) + goto add_key; + + memset(&rsaKeyParms, 0, sizeof(TCPA_RSA_KEY_PARMS)); + + rsakey->key.algorithmParms.algorithmID = TCPA_ALG_RSA; + rsakey->key.algorithmParms.parmSize = sizeof(TCPA_RSA_KEY_PARMS); + + rsakey->key.algorithmParms.parms = calloc(1, sizeof(TCPA_RSA_KEY_PARMS)); + if (rsakey->key.algorithmParms.parms == NULL) { + LogError("calloc of %u bytes failed.", rsakey->key.algorithmParms.parmSize); + free(rsakey); + return TSPERR(TSS_E_OUTOFMEMORY); + } + rsaKeyParms.exponentSize = 0; + rsaKeyParms.numPrimes = 2; + + rsakey->key.pubKey.keyLength = 0; + rsakey->key.encSize = 0; + rsakey->key.PCRInfoSize = 0; + + /* End of all the default stuff */ + + if (initFlags & TSS_KEY_VOLATILE) + rsakey->key.keyFlags |= TPM_VOLATILE; + if (initFlags & TSS_KEY_MIGRATABLE) + rsakey->key.keyFlags |= TPM_MIGRATABLE; + if (initFlags & TSS_KEY_AUTHORIZATION) { + rsakey->key.authDataUsage = TPM_AUTH_ALWAYS; + flags |= TSS_OBJ_FLAG_USAGEAUTH; + } + +#ifdef TSS_BUILD_CMK + if (initFlags & TSS_KEY_CERTIFIED_MIGRATABLE) { + if (rsakey->type == TSS_KEY_STRUCT_KEY) { + free(rsakey); + return TSPERR(TSS_E_BAD_PARAMETER); + } + rsakey->key.keyFlags |= TPM_MIGRATEAUTHORITY; + } +#endif + + /* set the key length */ + if ((initFlags & TSS_KEY_SIZE_MASK) == TSS_KEY_SIZE_512) { + rsaKeyParms.keyLength = 512; + } else if ((initFlags & TSS_KEY_SIZE_MASK) == TSS_KEY_SIZE_1024) { + rsaKeyParms.keyLength = 1024; + } else if ((initFlags & TSS_KEY_SIZE_MASK) == TSS_KEY_SIZE_2048) { + rsaKeyParms.keyLength = 2048; + } else if ((initFlags & TSS_KEY_SIZE_MASK) == TSS_KEY_SIZE_4096) { + rsaKeyParms.keyLength = 4096; + } else if ((initFlags & TSS_KEY_SIZE_MASK) == TSS_KEY_SIZE_8192) { + rsaKeyParms.keyLength = 8192; + } else if ((initFlags & TSS_KEY_SIZE_MASK) == TSS_KEY_SIZE_16384) { + rsaKeyParms.keyLength = 16384; + } + + /* assign encryption and signature schemes */ + if ((initFlags & TSS_KEY_TYPE_MASK) == TSS_KEY_TYPE_SIGNING) { + rsakey->key.keyUsage = TPM_KEY_SIGNING; + rsakey->key.algorithmParms.encScheme = TCPA_ES_NONE; + rsakey->key.algorithmParms.sigScheme = TCPA_SS_RSASSAPKCS1v15_SHA1; + } else if ((initFlags & TSS_KEY_TYPE_MASK) == TSS_KEY_TYPE_BIND) { + rsakey->key.keyUsage = TPM_KEY_BIND; + rsakey->key.algorithmParms.encScheme = TCPA_ES_RSAESOAEP_SHA1_MGF1; + rsakey->key.algorithmParms.sigScheme = TCPA_SS_NONE; + } else if ((initFlags & TSS_KEY_TYPE_MASK) == TSS_KEY_TYPE_LEGACY) { + rsakey->key.keyUsage = TPM_KEY_LEGACY; + rsakey->key.algorithmParms.encScheme = TCPA_ES_RSAESOAEP_SHA1_MGF1; + rsakey->key.algorithmParms.sigScheme = TCPA_SS_RSASSAPKCS1v15_SHA1; + } else if ((initFlags & TSS_KEY_TYPE_MASK) == TSS_KEY_TYPE_STORAGE) { + rsakey->key.keyUsage = TPM_KEY_STORAGE; + rsakey->key.algorithmParms.encScheme = TCPA_ES_RSAESOAEP_SHA1_MGF1; + rsakey->key.algorithmParms.sigScheme = TCPA_SS_NONE; + } else if ((initFlags & TSS_KEY_TYPE_MASK) == TSS_KEY_TYPE_IDENTITY) { + rsakey->key.keyUsage = TPM_KEY_IDENTITY; + rsakey->key.algorithmParms.encScheme = TCPA_ES_NONE; + rsakey->key.algorithmParms.sigScheme = TCPA_SS_RSASSAPKCS1v15_SHA1; + } else if ((initFlags & TSS_KEY_TYPE_MASK) == TSS_KEY_TYPE_AUTHCHANGE) { + rsakey->key.keyUsage = TPM_KEY_AUTHCHANGE; + rsakey->key.algorithmParms.encScheme = TCPA_ES_RSAESOAEP_SHA1_MGF1; + rsakey->key.algorithmParms.sigScheme = TCPA_SS_NONE; + } + + /* Load the RSA key parms into the blob in the TCPA_KEY_PARMS pointer. + * If the exponent is left NULL, the parmSize variable will change + * here */ + offset = 0; + Trspi_LoadBlob_RSA_KEY_PARMS(&offset, rsakey->key.algorithmParms.parms, &rsaKeyParms); + rsakey->key.algorithmParms.parmSize = offset; + +add_key: + if ((result = obj_list_add(&rsakey_list, tspContext, flags, rsakey, phObject))) { + free(rsakey->key.algorithmParms.parms); + free(rsakey); + return result; + } + + return TSS_SUCCESS; +} + +/* Add a new rsakey to the list when its pulled from user PS */ +TSS_RESULT +obj_rsakey_add_by_key(TSS_HCONTEXT tspContext, TSS_UUID *uuid, BYTE *key, TSS_FLAG flags, + TSS_HKEY *phKey) +{ + TSS_RESULT result; + UINT64 offset; + struct tr_rsakey_obj *rsakey = calloc(1, sizeof(struct tr_rsakey_obj)); + + if (rsakey == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(struct tr_rsakey_obj)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + memcpy(&rsakey->uuid, uuid, sizeof(TSS_UUID)); + + offset = 0; + if ((result = UnloadBlob_TSS_KEY(&offset, key, &rsakey->key))) { + free(rsakey); + return result; + } + if (rsakey->key.hdr.key12.tag == TPM_TAG_KEY12) + rsakey->type = TSS_KEY_STRUCT_KEY12; + else + rsakey->type = TSS_KEY_STRUCT_KEY; + + flags |= TSS_OBJ_FLAG_KEY_SET; + if (rsakey->key.authDataUsage) + flags |= TSS_OBJ_FLAG_USAGEAUTH; + + if ((result = obj_context_get_policy(tspContext, TSS_POLICY_USAGE, &rsakey->usagePolicy))) { + free(rsakey); + return result; + } + + if ((result = obj_list_add(&rsakey_list, tspContext, flags, rsakey, phKey))) { + free_key_refs(&rsakey->key); + free(rsakey); + return result; + } + + return TSS_SUCCESS; +} + +TSS_BOOL +obj_is_rsakey(TSS_HOBJECT hObject) +{ + TSS_BOOL answer = FALSE; + + if ((obj_list_get_obj(&rsakey_list, hObject))) { + answer = TRUE; + obj_list_put(&rsakey_list); + } + + return answer; +} + +TSS_RESULT +obj_rsakey_set_flags(TSS_HKEY hKey, UINT32 flags) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (obj->flags & TSS_OBJ_FLAG_KEY_SET) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + rsakey = (struct tr_rsakey_obj *)obj->data; + rsakey->key.keyFlags = flags; +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_set_size(TSS_HKEY hKey, UINT32 len) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (obj->flags & TSS_OBJ_FLAG_KEY_SET) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + rsakey = (struct tr_rsakey_obj *)obj->data; + rsakey->key.pubKey.keyLength = len/8; +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_set_key_parms(TSS_HKEY hKey, TCPA_KEY_PARMS *parms) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (obj->flags & TSS_OBJ_FLAG_KEY_SET) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + rsakey = (struct tr_rsakey_obj *)obj->data; + + free(rsakey->key.algorithmParms.parms); + + memcpy(&rsakey->key.algorithmParms, parms, sizeof(TCPA_KEY_PARMS)); + + if (parms->parmSize > 0) { + if ((rsakey->key.algorithmParms.parms = + malloc(parms->parmSize)) == NULL) { + LogError("calloc of %d bytes failed.", parms->parmSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + memcpy(rsakey->key.algorithmParms.parms, parms->parms, + parms->parmSize); + } else { + rsakey->key.algorithmParms.parms = NULL; + } + +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_set_policy(TSS_HKEY hKey, TSS_HPOLICY hPolicy) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + UINT32 policyType; + TSS_RESULT result = TSS_SUCCESS; + + if ((result = obj_policy_get_type(hPolicy, &policyType))) + return result; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + switch (policyType) { + case TSS_POLICY_USAGE: + rsakey->usagePolicy = hPolicy; + break; + case TSS_POLICY_MIGRATION: + rsakey->migPolicy = hPolicy; + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_set_pstype(TSS_HKEY hKey, UINT32 type) +{ + struct tsp_object *obj; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + switch (type) { + case TSS_PS_TYPE_USER: + obj->flags |= TSS_OBJ_FLAG_USER_PS; + obj->flags &= ~TSS_OBJ_FLAG_SYSTEM_PS; + break; + case TSS_PS_TYPE_SYSTEM: + obj->flags |= TSS_OBJ_FLAG_SYSTEM_PS; + obj->flags &= ~TSS_OBJ_FLAG_USER_PS; + break; + case TSS_PS_TYPE_NO: + default: + obj->flags &= ~TSS_OBJ_FLAG_USER_PS; + obj->flags &= ~TSS_OBJ_FLAG_SYSTEM_PS; + break; + } + + obj_list_put(&rsakey_list); + + return TSS_SUCCESS; +} + +/* WARN: Nobody should call this function directly except for the + * Get/Set Attrib functions. The TCPA_KEY structure wants values + * for keyUsage to be TPM_KEY_* values, and this function translates + * to TSS_KEYUSAGE_* values for passing to an app. */ +TSS_RESULT +obj_rsakey_get_usage(TSS_HKEY hKey, UINT32 *usage) +{ + TSS_RESULT result = TSS_SUCCESS; + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + switch (rsakey->key.keyUsage) { + case TPM_KEY_SIGNING: + *usage = TSS_KEYUSAGE_SIGN; + break; + case TPM_KEY_BIND: + *usage = TSS_KEYUSAGE_BIND; + break; + case TPM_KEY_LEGACY: + *usage = TSS_KEYUSAGE_LEGACY; + break; + case TPM_KEY_AUTHCHANGE: + *usage = TSS_KEYUSAGE_AUTHCHANGE; + break; + case TPM_KEY_IDENTITY: + *usage = TSS_KEYUSAGE_IDENTITY; + break; + case TPM_KEY_STORAGE: + *usage = TSS_KEYUSAGE_STORAGE; + break; + default: + result = TSPERR(TSS_E_INVALID_ATTRIB_DATA); + break; + } + + obj_list_put(&rsakey_list); + + return result; +} + +/* WARN: Nobody should call this function directly except for the + * Get/Set Attrib functions. The TCPA_KEY structure wants values + * for keyUsage to be TPM_KEY_* values, and this function translates + * to TSS_KEYUSAGE_* values for passing to an app. */ +TSS_RESULT +obj_rsakey_set_usage(TSS_HKEY hKey, UINT32 usage) +{ + TSS_RESULT result = TSS_SUCCESS; + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (obj->flags & TSS_OBJ_FLAG_KEY_SET) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + rsakey = (struct tr_rsakey_obj *)obj->data; + + switch (usage) { + case TSS_KEYUSAGE_SIGN: + rsakey->key.keyUsage = TPM_KEY_SIGNING; + break; + case TSS_KEYUSAGE_BIND: + rsakey->key.keyUsage = TPM_KEY_BIND; + break; + case TSS_KEYUSAGE_LEGACY: + rsakey->key.keyUsage = TPM_KEY_LEGACY; + break; + case TSS_KEYUSAGE_AUTHCHANGE: + rsakey->key.keyUsage = TPM_KEY_AUTHCHANGE; + break; + case TSS_KEYUSAGE_IDENTITY: + rsakey->key.keyUsage = TPM_KEY_IDENTITY; + break; + case TSS_KEYUSAGE_STORAGE: + rsakey->key.keyUsage = TPM_KEY_STORAGE; + break; + default: + result = TSPERR(TSS_E_INVALID_ATTRIB_DATA); + break; + } +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_set_migratable(TSS_HKEY hKey, UINT32 mig) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (obj->flags & TSS_OBJ_FLAG_KEY_SET) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + rsakey = (struct tr_rsakey_obj *)obj->data; + if (mig) + rsakey->key.keyFlags |= TPM_MIGRATABLE; + else + rsakey->key.keyFlags &= (~TPM_MIGRATABLE); +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_set_redirected(TSS_HKEY hKey, UINT32 redir) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (obj->flags & TSS_OBJ_FLAG_KEY_SET) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + rsakey = (struct tr_rsakey_obj *)obj->data; + if (redir) + rsakey->key.keyFlags |= TPM_REDIRECTION; + else + rsakey->key.keyFlags &= (~TPM_REDIRECTION); +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_set_volatile(TSS_HKEY hKey, UINT32 vol) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (obj->flags & TSS_OBJ_FLAG_KEY_SET) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + rsakey = (struct tr_rsakey_obj *)obj->data; + if (vol) + rsakey->key.keyFlags |= TPM_VOLATILE; + else + rsakey->key.keyFlags &= (~TPM_VOLATILE); +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_get_authdata_usage(TSS_HKEY hKey, UINT32 *usage) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + *usage = (UINT32)rsakey->key.authDataUsage ? TRUE : FALSE; + + obj_list_put(&rsakey_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_rsakey_set_authdata_usage(TSS_HKEY hKey, UINT32 usage) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (obj->flags & TSS_OBJ_FLAG_KEY_SET) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + rsakey = (struct tr_rsakey_obj *)obj->data; + + rsakey->key.authDataUsage = (BYTE)usage; + if (usage) + obj->flags |= TSS_OBJ_FLAG_USAGEAUTH; + else + obj->flags &= ~TSS_OBJ_FLAG_USAGEAUTH; +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_get_alg(TSS_HKEY hKey, UINT32 *alg) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + switch (rsakey->key.algorithmParms.algorithmID) { + case TCPA_ALG_RSA: + *alg = TSS_ALG_RSA; + break; + default: + *alg = rsakey->key.algorithmParms.algorithmID; + break; + } + + obj_list_put(&rsakey_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_rsakey_set_alg(TSS_HKEY hKey, UINT32 alg) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (obj->flags & TSS_OBJ_FLAG_KEY_SET) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + rsakey = (struct tr_rsakey_obj *)obj->data; + switch (alg) { + case TSS_ALG_RSA: + rsakey->key.algorithmParms.algorithmID = TCPA_ALG_RSA; + break; + default: + rsakey->key.algorithmParms.algorithmID = alg; + break; + } +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_get_es(TSS_HKEY hKey, UINT32 *es) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + /* translate TPM numbers to TSS numbers */ + switch (rsakey->key.algorithmParms.encScheme) { + case TCPA_ES_NONE: + *es = TSS_ES_NONE; + break; + case TCPA_ES_RSAESPKCSv15: + *es = TSS_ES_RSAESPKCSV15; + break; + case TCPA_ES_RSAESOAEP_SHA1_MGF1: + *es = TSS_ES_RSAESOAEP_SHA1_MGF1; + break; + default: + *es = rsakey->key.algorithmParms.encScheme; + break; + } + + obj_list_put(&rsakey_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_rsakey_set_es(TSS_HKEY hKey, UINT32 es) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (obj->flags & TSS_OBJ_FLAG_KEY_SET) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + rsakey = (struct tr_rsakey_obj *)obj->data; + + /* translate TSS numbers to TPM numbers */ + switch (es) { + case TSS_ES_NONE: + rsakey->key.algorithmParms.encScheme = TCPA_ES_NONE; + break; + case TSS_ES_RSAESPKCSV15: + rsakey->key.algorithmParms.encScheme = TCPA_ES_RSAESPKCSv15; + break; + case TSS_ES_RSAESOAEP_SHA1_MGF1: + rsakey->key.algorithmParms.encScheme = TCPA_ES_RSAESOAEP_SHA1_MGF1; + break; + default: + rsakey->key.algorithmParms.encScheme = es; + break; + } +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_get_ss(TSS_HKEY hKey, UINT32 *ss) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + /* translate TPM numbers to TSS numbers */ + switch (rsakey->key.algorithmParms.sigScheme) { + case TCPA_SS_NONE: + *ss = TSS_SS_NONE; + break; + case TCPA_SS_RSASSAPKCS1v15_SHA1: + *ss = TSS_SS_RSASSAPKCS1V15_SHA1; + break; + case TCPA_SS_RSASSAPKCS1v15_DER: + *ss = TSS_SS_RSASSAPKCS1V15_DER; + break; + case TCPA_SS_RSASSAPKCS1v15_INFO: + *ss = TSS_SS_RSASSAPKCS1V15_INFO; + break; + default: + *ss = rsakey->key.algorithmParms.sigScheme; + break; + } + + + obj_list_put(&rsakey_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_rsakey_set_ss(TSS_HKEY hKey, UINT32 ss) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (obj->flags & TSS_OBJ_FLAG_KEY_SET) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + rsakey = (struct tr_rsakey_obj *)obj->data; + + /* translate TSS numbers to TPM numbers */ + switch (ss) { + case TSS_SS_NONE: + rsakey->key.algorithmParms.sigScheme = TCPA_SS_NONE; + break; + case TSS_SS_RSASSAPKCS1V15_SHA1: + rsakey->key.algorithmParms.sigScheme = TCPA_SS_RSASSAPKCS1v15_SHA1; + break; + case TSS_SS_RSASSAPKCS1V15_DER: + rsakey->key.algorithmParms.sigScheme = TCPA_SS_RSASSAPKCS1v15_DER; + break; + case TSS_SS_RSASSAPKCS1V15_INFO: + rsakey->key.algorithmParms.sigScheme = TCPA_SS_RSASSAPKCS1v15_INFO; + break; + default: + rsakey->key.algorithmParms.sigScheme = ss; + break; + } +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_set_num_primes(TSS_HKEY hKey, UINT32 num) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (obj->flags & TSS_OBJ_FLAG_KEY_SET) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + rsakey = (struct tr_rsakey_obj *)obj->data; + UINT32ToArray(num, &rsakey->key.algorithmParms.parms[4]); +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_get_num_primes(TSS_HKEY hKey, UINT32 *num) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TCPA_RSA_KEY_PARMS *parms; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + parms = (TCPA_RSA_KEY_PARMS *)rsakey->key.algorithmParms.parms; + *num = endian32(parms->numPrimes); + + obj_list_put(&rsakey_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_rsakey_get_flags(TSS_HKEY hKey, UINT32 *flags) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + *flags = rsakey->key.keyFlags; + + obj_list_put(&rsakey_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_rsakey_get_size(TSS_HKEY hKey, UINT32 *len) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + switch (rsakey->key.pubKey.keyLength) { + case 512/8: + *len = TSS_KEY_SIZEVAL_512BIT; + break; + case 1024/8: + *len = TSS_KEY_SIZEVAL_1024BIT; + break; + case 2048/8: + *len = TSS_KEY_SIZEVAL_2048BIT; + break; + default: + *len = rsakey->key.pubKey.keyLength * 8; + break; + } + + obj_list_put(&rsakey_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_rsakey_get_pstype(TSS_HKEY hKey, UINT32 *type) +{ + struct tsp_object *obj; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (obj->flags & TSS_OBJ_FLAG_SYSTEM_PS) + *type = TSS_PS_TYPE_SYSTEM; + else if (obj->flags & TSS_OBJ_FLAG_USER_PS) + *type = TSS_PS_TYPE_USER; + else + *type = TSS_PS_TYPE_NO; + + obj_list_put(&rsakey_list); + + return TSS_SUCCESS; +} + +TSS_BOOL +obj_rsakey_is_migratable(TSS_HKEY hKey) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_BOOL answer = FALSE; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return answer; + + rsakey = (struct tr_rsakey_obj *)obj->data; + if (rsakey->key.keyFlags & TPM_MIGRATABLE) + answer = TRUE; + + obj_list_put(&rsakey_list); + + return answer; +} + +TSS_BOOL +obj_rsakey_is_redirected(TSS_HKEY hKey) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_BOOL answer = FALSE; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return answer; + + rsakey = (struct tr_rsakey_obj *)obj->data; + if (rsakey->key.keyFlags & TPM_REDIRECTION) + answer = TRUE; + + obj_list_put(&rsakey_list); + + return answer; +} + +TSS_BOOL +obj_rsakey_is_volatile(TSS_HKEY hKey) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_BOOL answer = FALSE; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return answer; + + rsakey = (struct tr_rsakey_obj *)obj->data; + if (rsakey->key.keyFlags & TPM_VOLATILE) + answer = TRUE; + + obj_list_put(&rsakey_list); + + return answer; +} + +TSS_RESULT +obj_rsakey_get_tsp_context(TSS_HKEY hKey, TSS_HCONTEXT *tspContext) +{ + struct tsp_object *obj; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + *tspContext = obj->tspContext; + + obj_list_put(&rsakey_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_rsakey_get_policies(TSS_HKEY hKey, TSS_HPOLICY *usage, TSS_HPOLICY *mig, TSS_BOOL *auth) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + *mig = rsakey->migPolicy; + *usage = rsakey->usagePolicy; + *auth = rsakey->key.authDataUsage ? TRUE : FALSE; + + obj_list_put(&rsakey_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_rsakey_get_policy(TSS_HKEY hKey, UINT32 policyType, + TSS_HPOLICY *phPolicy, TSS_BOOL *auth) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + switch (policyType) { + case TSS_POLICY_USAGE: + *phPolicy = rsakey->usagePolicy; + if (auth != NULL) { + if (obj->flags & TSS_OBJ_FLAG_USAGEAUTH) + *auth = TRUE; + else + *auth = FALSE; + } + break; + case TSS_POLICY_MIGRATION: + if (!rsakey->migPolicy) { + result = TSPERR(TSS_E_KEY_NO_MIGRATION_POLICY); + break; + } + + *phPolicy = rsakey->migPolicy; + if (auth != NULL) { + if (obj->flags & TSS_OBJ_FLAG_MIGAUTH) + *auth = TRUE; + else + *auth = FALSE; + } + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_get_blob(TSS_HKEY hKey, UINT32 *size, BYTE **data) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + UINT64 offset; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + offset = 0; + LoadBlob_TSS_KEY(&offset, NULL, &rsakey->key); + + *data = calloc_tspi(obj->tspContext, offset); + if (*data == NULL) { + LogError("malloc of %" PRIu64 " bytes failed.", offset); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + offset = 0; + LoadBlob_TSS_KEY(&offset, *data, &rsakey->key); + *size = offset; + +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_get_priv_blob(TSS_HKEY hKey, UINT32 *size, BYTE **data) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + *data = calloc_tspi(obj->tspContext, rsakey->key.encSize); + if (*data == NULL) { + LogError("malloc of %u bytes failed.", rsakey->key.encSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + *size = rsakey->key.encSize; + memcpy(*data, rsakey->key.encData, rsakey->key.encSize); + +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_get_modulus(TSS_HKEY hKey, UINT32 *size, BYTE **data) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + /* if this key object represents the SRK and the public key + * data here is all 0's, then we shouldn't return it, we + * should return TSS_E_BAD_PARAMETER. This is part of protecting + * the SRK public key. */ + if (rsakey->tcsHandle == TPM_KEYHND_SRK) { + BYTE zeroBlob[2048] = { 0, }; + + if (!memcmp(rsakey->key.pubKey.key, zeroBlob, rsakey->key.pubKey.keyLength)) { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + } + + *data = calloc_tspi(obj->tspContext, rsakey->key.pubKey.keyLength); + if (*data == NULL) { + LogError("malloc of %u bytes failed.", rsakey->key.pubKey.keyLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + *size = rsakey->key.pubKey.keyLength; + memcpy(*data, rsakey->key.pubKey.key, rsakey->key.pubKey.keyLength); + +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_set_modulus(TSS_HKEY hKey, UINT32 size, BYTE *data) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + BYTE *free_ptr; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (obj->flags & TSS_OBJ_FLAG_KEY_SET) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + rsakey = (struct tr_rsakey_obj *)obj->data; + + free_ptr = rsakey->key.pubKey.key; + + rsakey->key.pubKey.key = malloc(size); + if (rsakey->key.pubKey.key == NULL) { + rsakey->key.pubKey.key = free_ptr; // restore + LogError("malloc of %u bytes failed.", size); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + rsakey->key.pubKey.keyLength = size; + memcpy(rsakey->key.pubKey.key, data, size); + +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_get_pub_blob(TSS_HKEY hKey, UINT32 *size, BYTE **data) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + UINT64 offset; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + /* if this key object represents the SRK and the public key + * data here is all 0's, then we shouldn't return it, we + * should return TSS_E_BAD_PARAMETER. This is part of protecting + * the SRK public key. */ + if (rsakey->tcsHandle == TPM_KEYHND_SRK) { + BYTE zeroBlob[2048] = { 0, }; + + if (!memcmp(rsakey->key.pubKey.key, zeroBlob, rsakey->key.pubKey.keyLength)) { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + } + + offset = 0; + Trspi_LoadBlob_KEY_PARMS(&offset, NULL, &rsakey->key.algorithmParms); + Trspi_LoadBlob_STORE_PUBKEY(&offset, NULL, &rsakey->key.pubKey); + + *data = calloc_tspi(obj->tspContext, offset); + if (*data == NULL) { + LogError("malloc of %" PRIu64 " bytes failed.", offset); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + offset = 0; + Trspi_LoadBlob_KEY_PARMS(&offset, *data, &rsakey->key.algorithmParms); + Trspi_LoadBlob_STORE_PUBKEY(&offset, *data, &rsakey->key.pubKey); + *size = offset; + +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_get_version(TSS_HKEY hKey, UINT32 *size, BYTE **data) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + UINT64 offset; + TPM_STRUCT_VER ver = {1, 2, 0, 0}, *pVer; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + if (rsakey->key.hdr.key12.tag == TPM_TAG_KEY12) + pVer = &ver; + else + pVer = &rsakey->key.hdr.key11.ver; + + offset = 0; + Trspi_LoadBlob_TCPA_VERSION(&offset, NULL, *pVer); + + *data = calloc_tspi(obj->tspContext, offset); + if (*data == NULL) { + LogError("malloc of %" PRIu64 " bytes failed.", offset); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + offset = 0; + Trspi_LoadBlob_TCPA_VERSION(&offset, *data, *pVer); + *size = offset; + +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_get_exponent(TSS_HKEY hKey, UINT32 *size, BYTE **data) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + TCPA_RSA_KEY_PARMS *parms; + BYTE default_exp[3] = { 0x1, 0x0, 0x1 }; + UINT32 offset; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + parms = (TCPA_RSA_KEY_PARMS *)rsakey->key.algorithmParms.parms; + offset = parms->exponentSize; + + /* see TPM 1.1b spec pg. 51. If exponentSize is 0, we're using the + * default exponent of 2^16 + 1. */ + if (offset == 0) { + offset = 3; + *data = calloc_tspi(obj->tspContext, offset); + if (*data == NULL) { + LogError("malloc of %u bytes failed.", offset); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + *size = offset; + memcpy(*data, default_exp, offset); + } else { + *data = calloc_tspi(obj->tspContext, offset); + if (*data == NULL) { + LogError("malloc of %u bytes failed.", offset); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + *size = offset; + memcpy(*data, parms->exponent, offset); + } + +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_set_exponent(TSS_HKEY hKey, UINT32 size, BYTE *data) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + TCPA_RSA_KEY_PARMS *parms; + BYTE *free_ptr; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (obj->flags & TSS_OBJ_FLAG_KEY_SET) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + rsakey = (struct tr_rsakey_obj *)obj->data; + parms = (TCPA_RSA_KEY_PARMS *)rsakey->key.algorithmParms.parms; + + free_ptr = parms->exponent; + + parms->exponent = malloc(size); + if (parms->exponent == NULL) { + parms->exponent = free_ptr; // restore + LogError("malloc of %u bytes failed.", size); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + parms->exponentSize = size; + memcpy(parms->exponent, data, size); +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_get_uuid(TSS_HKEY hKey, UINT32 *size, BYTE **data) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + UINT64 offset; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + offset = 0; + Trspi_LoadBlob_UUID(&offset, NULL, rsakey->uuid); + + *data = calloc_tspi(obj->tspContext, offset); + if (*data == NULL) { + LogError("malloc of %" PRIu64 " bytes failed.", offset); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + offset = 0; + Trspi_LoadBlob_UUID(&offset, *data, rsakey->uuid); + *size = offset; + +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_set_uuid(TSS_HKEY hKey, TSS_FLAG ps_type, TSS_UUID *uuid) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + memcpy(&rsakey->uuid, uuid, sizeof(TSS_UUID)); + + switch (ps_type) { + case TSS_PS_TYPE_SYSTEM: + obj->flags |= TSS_OBJ_FLAG_SYSTEM_PS; + obj->flags &= ~TSS_OBJ_FLAG_USER_PS; + break; + case TSS_PS_TYPE_USER: + obj->flags |= TSS_OBJ_FLAG_USER_PS; + obj->flags &= ~TSS_OBJ_FLAG_SYSTEM_PS; + break; + case TSS_PS_TYPE_NO: + default: + obj->flags &= ~TSS_OBJ_FLAG_USER_PS; + obj->flags &= ~TSS_OBJ_FLAG_SYSTEM_PS; + break; + } + + obj_list_put(&rsakey_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_rsakey_set_tcs_handle(TSS_HKEY hKey, TCS_KEY_HANDLE tcsHandle) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + rsakey->tcsHandle = tcsHandle; + + obj_list_put(&rsakey_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_rsakey_get_tcs_handle(TSS_HKEY hKey, TCS_KEY_HANDLE *tcsHandle) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + if (rsakey->tcsHandle) + *tcsHandle = rsakey->tcsHandle; + else + result = TSPERR(TSS_E_KEY_NOT_LOADED); + + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_set_tcpakey(TSS_HKEY hKey, UINT32 size, BYTE *data) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + UINT64 offset; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + free_key_refs(&rsakey->key); + + offset = 0; + if ((result = UnloadBlob_TSS_KEY(&offset, data, &rsakey->key))) + goto done; + if (rsakey->key.hdr.key12.tag == TPM_TAG_KEY12) + rsakey->type = TSS_KEY_STRUCT_KEY12; + else + rsakey->type = TSS_KEY_STRUCT_KEY; + + if (rsakey->key.authDataUsage) + obj->flags |= TSS_OBJ_FLAG_USAGEAUTH; + else + obj->flags &= ~TSS_OBJ_FLAG_USAGEAUTH; + + if (rsakey->key.PCRInfoSize && rsakey->key.PCRInfo) { + offset = 0; + if (rsakey->type == TSS_KEY_STRUCT_KEY12) { + if ((result = Trspi_UnloadBlob_PCR_INFO_LONG(&offset, rsakey->key.PCRInfo, + &rsakey->pcrInfo.infolong))) + goto done; + } else { + if ((result = Trspi_UnloadBlob_PCR_INFO(&offset, rsakey->key.PCRInfo, + &rsakey->pcrInfo.info11))) + goto done; + } + } + + obj->flags |= TSS_OBJ_FLAG_KEY_SET; +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_get_pcr_digest(TSS_HKEY hKey, + TSS_FLAG pcrInfoType, + TSS_FLAG dir, + UINT32 *size, + BYTE **data) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + TPM_DIGEST *digest = NULL; + UINT64 offset; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + if (pcrInfoType != rsakey->pcrInfoType) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + switch (pcrInfoType) { + case TSS_PCRS_STRUCT_INFO: + if (dir == TSS_TSPATTRIB_KEYPCR_DIGEST_ATCREATION) + digest = &rsakey->pcrInfo.info11.digestAtCreation; + else if (dir == TSS_TSPATTRIB_KEYPCR_DIGEST_ATRELEASE) + digest = &rsakey->pcrInfo.info11.digestAtRelease; + else { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + break; + case TSS_PCRS_STRUCT_INFO_LONG: + if (dir == TSS_TSPATTRIB_KEYPCRLONG_DIGEST_ATCREATION) + digest = &rsakey->pcrInfo.infolong.digestAtCreation; + else if (dir == TSS_TSPATTRIB_KEYPCRLONG_DIGEST_ATRELEASE) + digest = &rsakey->pcrInfo.infolong.digestAtRelease; + else { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + break; + default: + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *size = sizeof(TPM_DIGEST); + + if ((*data = calloc_tspi(obj->tspContext, *size)) == NULL) { + LogError("malloc of %u bytes failed.", *size); + *size = 0; + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + offset = 0; + Trspi_LoadBlob_DIGEST(&offset, *data, digest); +done: + obj_list_put(&rsakey_list); + + return result; +} + + +TSS_RESULT +obj_rsakey_get_pcr_locality(TSS_HKEY hKey, TSS_FLAG dir, UINT32 *locality) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + if (rsakey->pcrInfoType == TSS_PCRS_STRUCT_INFO_LONG) { + if (dir == TSS_TSPATTRIB_KEYPCRLONG_LOCALITY_ATCREATION) + *locality = rsakey->pcrInfo.infolong.localityAtCreation; + else if (dir == TSS_TSPATTRIB_KEYPCRLONG_LOCALITY_ATRELEASE) + *locality = rsakey->pcrInfo.infolong.localityAtRelease; + else + result = TSPERR(TSS_E_BAD_PARAMETER); + } else + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_get_pcr_selection(TSS_HKEY hKey, + UINT32 pcrInfoType, + TSS_FLAG dir, + UINT32 *size, + BYTE **data) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + UINT64 offset; + TPM_PCR_SELECTION *selection = NULL; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + if (pcrInfoType != rsakey->pcrInfoType) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + switch (pcrInfoType) { + case TSS_PCRS_STRUCT_INFO: + if (dir == TSS_TSPATTRIB_KEYPCR_SELECTION) + selection = &rsakey->pcrInfo.info11.pcrSelection; + else { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + break; + case TSS_PCRS_STRUCT_INFO_LONG: + if (dir == TSS_TSPATTRIB_KEYPCRLONG_CREATION_SELECTION) + selection = &rsakey->pcrInfo.infolong.creationPCRSelection; + else if (dir == TSS_TSPATTRIB_KEYPCRLONG_RELEASE_SELECTION) + selection = &rsakey->pcrInfo.infolong.releasePCRSelection; + else { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + break; + default: + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *size = sizeof(UINT16) + selection->sizeOfSelect; + + if ((*data = calloc_tspi(obj->tspContext, *size)) == NULL) { + LogError("malloc of %u bytes failed.", *size); + *size = 0; + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + offset = 0; + Trspi_LoadBlob_PCR_SELECTION(&offset, *data, selection); + +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +rsakey_set_pubkey(struct tr_rsakey_obj *rsakey, BYTE *pubkey) +{ + TSS_RESULT result; + UINT64 offset = 0; + TPM_PUBKEY pub; + + if ((result = Trspi_UnloadBlob_PUBKEY(&offset, pubkey, &pub))) + return result; + + free(rsakey->key.pubKey.key); + free(rsakey->key.algorithmParms.parms); + + memcpy(&rsakey->key.pubKey, &pub.pubKey, sizeof(TPM_STORE_PUBKEY)); + memcpy(&rsakey->key.algorithmParms, &pub.algorithmParms, sizeof(TPM_KEY_PARMS)); + + return TSS_SUCCESS; +} + +/* Expect a TPM_PUBKEY as is explained in the portable data section of the spec */ +TSS_RESULT +obj_rsakey_set_pubkey(TSS_HKEY hKey, UINT32 force, BYTE *data) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + if (!force && (obj->flags & TSS_OBJ_FLAG_KEY_SET)) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + result = rsakey_set_pubkey(rsakey, data); +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_set_srk_pubkey(BYTE *pubkey) +{ + struct tsp_object *obj; + struct obj_list *list = &rsakey_list; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result; + + MUTEX_LOCK(list->lock); + + for (obj = list->head; obj; obj = obj->next) { + rsakey = (struct tr_rsakey_obj *)obj->data; + + /* we found the SRK, set this data as its public key */ + if (rsakey->tcsHandle == TPM_KEYHND_SRK) { + result = rsakey_set_pubkey(rsakey, pubkey); + MUTEX_UNLOCK(list->lock); + return result; + } + } + + MUTEX_UNLOCK(list->lock); + + return TSPERR(TSS_E_INVALID_HANDLE); +} + +TSS_RESULT +obj_rsakey_set_privkey(TSS_HKEY hKey, UINT32 force, UINT32 size, BYTE *data) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + void *to_free; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (!force && (obj->flags & TSS_OBJ_FLAG_KEY_SET)) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + rsakey = (struct tr_rsakey_obj *)obj->data; + + to_free = rsakey->key.encData; + + rsakey->key.encData = calloc(1, size); + if (rsakey->key.encData == NULL) { + rsakey->key.encData = to_free; // restore + LogError("malloc of %u bytes failed.", size); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + free(to_free); + rsakey->key.encSize = size; + memcpy(rsakey->key.encData, data, size); +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_set_pcr_data(TSS_HKEY hKey, TSS_HPCRS hPcrComposite) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + UINT32 pcrType, pcrSize; + BYTE *pcrInfo; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (obj->flags & TSS_OBJ_FLAG_KEY_SET) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + rsakey = (struct tr_rsakey_obj *)obj->data; + + /* passing in a pcrType of TSS_PCRS_STRUCT_DEFAULT will tell the pcr routine to create + * a structure matching the type of the hPcrComposite object */ + pcrType = TSS_PCRS_STRUCT_DEFAULT; + if ((result = obj_pcrs_create_info_type(hPcrComposite, &pcrType, &pcrSize, &pcrInfo))) + goto done; + + rsakey->key.PCRInfo = pcrInfo; + rsakey->key.PCRInfoSize = pcrSize; +done: + obj_list_put(&rsakey_list); + + return result; +} + +void +__tspi_rsakey_free(void *data) +{ + struct tr_rsakey_obj *rsakey = (struct tr_rsakey_obj *)data; + + free(rsakey->key.algorithmParms.parms); + free(rsakey->key.encData); + free(rsakey->key.PCRInfo); + free(rsakey->key.pubKey.key); + free(rsakey); +} + +/* Remove an individual rsakey object from the rsakey list with handle + * equal to hObject. Clean up the TSP's key handle table. */ +TSS_RESULT +obj_rsakey_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext) +{ + TSS_RESULT result; + + if ((result = obj_list_remove(&rsakey_list, &__tspi_rsakey_free, hObject, tspContext))) + return result; + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_rsakey_get_by_pub(UINT32 pub_size, BYTE *pub, TSS_HKEY *hKey) +{ + struct obj_list *list = &rsakey_list; + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + MUTEX_LOCK(list->lock); + + for (obj = list->head; obj; obj = obj->next) { + rsakey = (struct tr_rsakey_obj *)obj->data; + + if (rsakey->key.pubKey.keyLength == pub_size && + !memcmp(&rsakey->key.pubKey.key, pub, pub_size)) { + *hKey = obj->handle; + goto done; + } + } + + *hKey = 0; +done: + MUTEX_UNLOCK(list->lock); + + return result; +} + +TSS_RESULT +obj_rsakey_get_by_uuid(TSS_UUID *uuid, TSS_HKEY *hKey) +{ + struct obj_list *list = &rsakey_list; + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + MUTEX_LOCK(list->lock); + + for (obj = list->head; obj; obj = obj->next) { + rsakey = (struct tr_rsakey_obj *)obj->data; + + if (!memcmp(&rsakey->uuid, uuid, sizeof(TSS_UUID))) { + *hKey = obj->handle; + goto done; + } + } + + result = TSPERR(TSS_E_PS_KEY_NOTFOUND); +done: + MUTEX_UNLOCK(list->lock); + + return result; +} + +void +obj_rsakey_remove_policy_refs(TSS_HPOLICY hPolicy, TSS_HCONTEXT tspContext) +{ + struct tsp_object *obj; + struct obj_list *list = &rsakey_list; + struct tr_rsakey_obj *rsakey; + + MUTEX_LOCK(list->lock); + + for (obj = list->head; obj; obj = obj->next) { + if (obj->tspContext != tspContext) + continue; + + rsakey = (struct tr_rsakey_obj *)obj->data; + if (rsakey->usagePolicy == hPolicy) + rsakey->usagePolicy = NULL_HPOLICY; + + if (rsakey->migPolicy == hPolicy) + rsakey->migPolicy = NULL_HPOLICY; + } + + MUTEX_UNLOCK(list->lock); +} + +#if 0 +TSS_RESULT +obj_rsakey_get_transport_attribs(TSS_HKEY hKey, TCS_KEY_HANDLE *hTCSKey, TPM_DIGEST *pubDigest) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result; + Trspi_HashCtx hashCtx; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + *hTCSKey = rsakey->tcsHandle; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_STORE_PUBKEY(&hashCtx, &rsakey->key.pubKey); + result |= Trspi_HashFinal(&hashCtx, pubDigest->digest); + + obj_list_put(&rsakey_list); + + return result; +} +#endif + +#ifdef TSS_BUILD_CMK +TSS_BOOL +obj_rsakey_is_cmk(TSS_HKEY hKey) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_BOOL answer = FALSE; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return answer; + + rsakey = (struct tr_rsakey_obj *)obj->data; + if (rsakey->type != TSS_KEY_STRUCT_KEY) { + if (rsakey->key.keyFlags & TPM_MIGRATEAUTHORITY) + answer = TRUE; + } + + obj_list_put(&rsakey_list); + + return answer; +} + +TSS_RESULT +obj_rsakey_set_cmk(TSS_HKEY hKey, UINT32 cmk) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (obj->flags & TSS_OBJ_FLAG_KEY_SET) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + rsakey = (struct tr_rsakey_obj *)obj->data; + if (rsakey->type == TSS_KEY_STRUCT_KEY) { + result = TSPERR(TSS_E_INVALID_OBJ_ACCESS); + goto done; + } + + if (cmk) + rsakey->key.keyFlags |= TPM_MIGRATEAUTHORITY; + else + rsakey->key.keyFlags &= (~TPM_MIGRATEAUTHORITY); + +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_set_msa_approval(TSS_HKEY hKey, UINT32 blobSize, BYTE *blob) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + if (blobSize != sizeof(rsakey->msaApproval.digest)) { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + memcpy(rsakey->msaApproval.digest, blob, sizeof(rsakey->msaApproval.digest)); + +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_get_msa_approval(TSS_HKEY hKey, UINT32 *blobSize, BYTE **blob) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + if ((*blob = calloc_tspi(obj->tspContext, sizeof(rsakey->msaApproval.digest))) == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(rsakey->msaApproval.digest)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(*blob, rsakey->msaApproval.digest, sizeof(rsakey->msaApproval.digest)); + *blobSize = sizeof(rsakey->msaApproval.digest); + +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_set_msa_digest(TSS_HKEY hKey, UINT32 blobSize, BYTE *blob) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + if (blobSize != sizeof(rsakey->msaDigest.digest)) { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + memcpy(rsakey->msaDigest.digest, blob, sizeof(rsakey->msaDigest.digest)); + +done: + obj_list_put(&rsakey_list); + + return result; +} + +TSS_RESULT +obj_rsakey_get_msa_digest(TSS_HKEY hKey, UINT32 *blobSize, BYTE **blob) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + if ((*blob = calloc_tspi(obj->tspContext, sizeof(rsakey->msaDigest.digest))) == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(rsakey->msaDigest.digest)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(*blob, rsakey->msaDigest.digest, sizeof(rsakey->msaDigest.digest)); + *blobSize = sizeof(rsakey->msaDigest.digest); + +done: + obj_list_put(&rsakey_list); + + return result; +} +#endif + +TSS_RESULT +obj_rsakey_get_ownerevict(TSS_HKEY hKey, UINT32 *value) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + *value = rsakey->flags & TSS_RSAKEY_FLAG_OWNEREVICT; + + obj_list_put(&rsakey_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_rsakey_set_ownerevict(TSS_HKEY hKey, TSS_BOOL value) +{ + struct tsp_object *obj; + struct tr_rsakey_obj *rsakey; + + if ((obj = obj_list_get_obj(&rsakey_list, hKey)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + rsakey = (struct tr_rsakey_obj *)obj->data; + + if (value) + rsakey->flags |= TSS_RSAKEY_FLAG_OWNEREVICT; + else + rsakey->flags &= ~TSS_RSAKEY_FLAG_OWNEREVICT; + + obj_list_put(&rsakey_list); + + return TSS_SUCCESS; +} diff --git a/src/tspi/obj_tpm.c b/src/tspi/obj_tpm.c new file mode 100644 index 0000000..586b875 --- /dev/null +++ b/src/tspi/obj_tpm.c @@ -0,0 +1,531 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2005, 2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + +void +tpm_free(void *data) +{ + struct tr_tpm_obj *tpm = (struct tr_tpm_obj *)data; + + free(tpm); +} + +TSS_RESULT +obj_tpm_add(TSS_HCONTEXT tspContext, TSS_HOBJECT *phObject) +{ + TSS_RESULT result; + struct tr_tpm_obj *tpm = calloc(1, sizeof(struct tr_tpm_obj)); + + if (tpm == NULL) { + LogError("malloc of %zd bytes failed.", + sizeof(struct tr_tpm_obj)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + /* add usage policy */ + if ((result = obj_policy_add(tspContext, TSS_POLICY_USAGE, + &tpm->policy))) { + free(tpm); + return result; + } + + /* initialize the default ctr_id to inactive until we query the TPM */ + tpm->ctr_id = 0xffffffff; + + if ((result = obj_list_add(&tpm_list, tspContext, 0, tpm, phObject))) { + free(tpm); + return result; + } + + return TSS_SUCCESS; +} + +TSS_BOOL +obj_is_tpm(TSS_HOBJECT hObject) +{ + TSS_BOOL answer = FALSE; + + if ((obj_list_get_obj(&tpm_list, hObject))) { + answer = TRUE; + obj_list_put(&tpm_list); + } + + return answer; +} + +TSS_RESULT +obj_tpm_set_policy(TSS_HTPM hTpm, TSS_HPOLICY hPolicy) +{ + struct tsp_object *obj; + struct tr_tpm_obj *tpm; + UINT32 policyType; + TSS_RESULT result = TSS_SUCCESS; + + if ((result = obj_policy_get_type(hPolicy, &policyType))) + return result; + + if ((obj = obj_list_get_obj(&tpm_list, hTpm)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + tpm = (struct tr_tpm_obj *)obj->data; + + switch (policyType) { + case TSS_POLICY_USAGE: + tpm->policy = hPolicy; + break; +#ifdef TSS_BUILD_TSS12 + case TSS_POLICY_OPERATOR: + tpm->operatorPolicy = hPolicy; + break; +#endif + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + obj_list_put(&tpm_list); + + return result; +} + +TSS_RESULT +obj_tpm_get_policy(TSS_HTPM hTpm, UINT32 policyType, TSS_HPOLICY *phPolicy) +{ + struct tsp_object *obj; + struct tr_tpm_obj *tpm; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&tpm_list, hTpm)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + tpm = (struct tr_tpm_obj *)obj->data; + + switch (policyType) { + case TSS_POLICY_USAGE: + *phPolicy = tpm->policy; + break; +#ifdef TSS_BUILD_TSS12 + case TSS_POLICY_OPERATOR: + *phPolicy = tpm->operatorPolicy; + break; +#endif + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + obj_list_put(&tpm_list); + + return result; +} + +TSS_RESULT +obj_tpm_get_tsp_context(TSS_HTPM hTpm, TSS_HCONTEXT *tspContext) +{ + struct tsp_object *obj; + + if ((obj = obj_list_get_obj(&tpm_list, hTpm)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + *tspContext = obj->tspContext; + + obj_list_put(&tpm_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_tpm_get(TSS_HCONTEXT tspContext, TSS_HTPM *phTpm) +{ + struct tsp_object *obj; + + if ((obj = obj_list_get_tspcontext(&tpm_list, tspContext)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + *phTpm = obj->handle; + + obj_list_put(&tpm_list); + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_tpm_get_cb11(TSS_HTPM hTpm, TSS_FLAG type, UINT32 *cb) +{ +#ifndef __LP64__ + struct tsp_object *obj; + struct tr_tpm_obj *tpm; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&tpm_list, hTpm)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + tpm = (struct tr_tpm_obj *)obj->data; + + switch (type) { + case TSS_TSPATTRIB_TPM_CALLBACK_COLLATEIDENTITY: + *cb = (UINT32)tpm->Tspicb_CollateIdentity; + break; + case TSS_TSPATTRIB_TPM_CALLBACK_ACTIVATEIDENTITY: + *cb = (UINT32)tpm->Tspicb_ActivateIdentity; + break; + default: + result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } + + obj_list_put(&tpm_list); + + return result; +#else + return TSPERR(TSS_E_FAIL); +#endif +} + +TSS_RESULT +obj_tpm_set_cb11(TSS_HTPM hTpm, TSS_FLAG type, TSS_FLAG app_data, UINT32 cb) +{ +#ifndef __LP64__ + struct tsp_object *obj; + struct tr_tpm_obj *tpm; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&tpm_list, hTpm)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + tpm = (struct tr_tpm_obj *)obj->data; + + switch (type) { + case TSS_TSPATTRIB_TPM_CALLBACK_COLLATEIDENTITY: + tpm->Tspicb_CollateIdentity = (PVOID)cb; + tpm->collateAppData = (PVOID)app_data; + break; + case TSS_TSPATTRIB_TPM_CALLBACK_ACTIVATEIDENTITY: + tpm->Tspicb_ActivateIdentity = (PVOID)cb; + tpm->activateAppData = (PVOID)app_data; + break; + default: + result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } + + obj_list_put(&tpm_list); + + return result; +#else + return TSPERR(TSS_E_FAIL); +#endif +} + +TSS_RESULT +obj_tpm_set_cred(TSS_HTPM hTpm, TSS_FLAG type, UINT32 CredSize, BYTE *CredData) +{ + struct tsp_object *obj; + struct tr_tpm_obj *tpm; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&tpm_list, hTpm)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + tpm = (struct tr_tpm_obj *)obj->data; + + switch (type) { + case TSS_TPMATTRIB_EKCERT: + if ((tpm->EndorsementCred = malloc(CredSize)) == NULL) { + LogError("malloc of %u bytes failed", CredSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(tpm->EndorsementCred, CredData, CredSize); + tpm->EndorsementCredSize = CredSize; + break; + case TSS_TPMATTRIB_TPM_CC: + if ((tpm->ConformanceCred = malloc(CredSize)) == NULL) { + LogError("malloc of %u bytes failed", CredSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(tpm->ConformanceCred, CredData, CredSize); + tpm->ConformanceCredSize = CredSize; + break; + case TSS_TPMATTRIB_PLATFORMCERT: + if ((tpm->PlatformCred = malloc(CredSize)) == NULL) { + LogError("malloc of %u bytes failed", CredSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(tpm->PlatformCred, CredData, CredSize); + tpm->PlatformCredSize = CredSize; + break; + case TSS_TPMATTRIB_PLATFORM_CC: + if ((tpm->PlatformConfCred = malloc(CredSize)) == NULL) { + LogError("malloc of %u bytes failed", CredSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(tpm->PlatformConfCred, CredData, CredSize); + tpm->PlatformConfCredSize = CredSize; + break; + default: + result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } +done: + obj_list_put(&tpm_list); + + return result; +} + +TSS_RESULT +obj_tpm_get_cred(TSS_HTPM hTpm, TSS_FLAG type, UINT32 *CredSize, BYTE **CredData) +{ + struct tsp_object *obj; + struct tr_tpm_obj *tpm; + TSS_RESULT result = TSS_SUCCESS; + + if ((obj = obj_list_get_obj(&tpm_list, hTpm)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + tpm = (struct tr_tpm_obj *)obj->data; + + /* get the size of data we need to allocate */ + switch (type) { + case TSS_TPMATTRIB_EKCERT: + *CredSize = tpm->EndorsementCredSize; + break; + case TSS_TPMATTRIB_TPM_CC: + *CredSize = tpm->ConformanceCredSize; + break; + case TSS_TPMATTRIB_PLATFORMCERT: + *CredSize = tpm->PlatformCredSize; + break; + case TSS_TPMATTRIB_PLATFORM_CC: + *CredSize = tpm->PlatformConfCredSize; + break; + default: + LogError("Credential type is unknown"); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + if (*CredSize == 0) { + *CredData = NULL; + goto done; + } + + if ((*CredData = calloc_tspi(obj->tspContext, *CredSize)) == NULL) { + *CredSize = 0; + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + switch (type) { + case TSS_TPMATTRIB_EKCERT: + memcpy(*CredData, tpm->EndorsementCred, *CredSize); + break; + case TSS_TPMATTRIB_TPM_CC: + memcpy(*CredData, tpm->ConformanceCred, *CredSize); + break; + case TSS_TPMATTRIB_PLATFORMCERT: + memcpy(*CredData, tpm->PlatformCred, *CredSize); + break; + case TSS_TPMATTRIB_PLATFORM_CC: + memcpy(*CredData, tpm->PlatformConfCred, *CredSize); + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + *CredSize = 0; + free(*CredData); + *CredData = NULL; + break; + } + +done: + obj_list_put(&tpm_list); + return result; +} + +TSS_RESULT +obj_tpm_set_cb12(TSS_HTPM hTpm, TSS_FLAG flag, BYTE *in) +{ + struct tsp_object *obj; + struct tr_tpm_obj *tpm; + TSS_RESULT result = TSS_SUCCESS; + TSS_CALLBACK *cb = (TSS_CALLBACK *)in; + + if ((obj = obj_list_get_obj(&tpm_list, hTpm)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + tpm = (struct tr_tpm_obj *)obj->data; + + switch (flag) { + case TSS_TSPATTRIB_TPM_CALLBACK_COLLATEIDENTITY: + if (!cb) { + tpm->Tspicb_CollateIdentity = NULL; + break; + } + + tpm->Tspicb_CollateIdentity = (TSS_RESULT (*)(PVOID, + UINT32, BYTE *, TSS_ALGORITHM_ID, UINT32 *, + BYTE *, UINT32 *, BYTE *))cb->callback; + tpm->collateAppData = cb->appData; + tpm->collateAlg = cb->alg; + break; + case TSS_TSPATTRIB_TPM_CALLBACK_ACTIVATEIDENTITY: + if (!cb) { + tpm->Tspicb_ActivateIdentity = NULL; + break; + } + + tpm->Tspicb_ActivateIdentity = (TSS_RESULT (*)(PVOID, + UINT32, BYTE *, UINT32, BYTE *, UINT32 *, + BYTE *))cb->callback; + tpm->activateAppData = cb->appData; + tpm->activateAlg = cb->alg; + break; + default: + result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } + + obj_list_put(&tpm_list); + + return result; +} + +TSS_RESULT +obj_tpm_get_cb12(TSS_HTPM hTpm, TSS_FLAG flag, UINT32 *size, BYTE **out) +{ + struct tsp_object *obj; + struct tr_tpm_obj *tpm; + TSS_RESULT result = TSS_SUCCESS; + TSS_CALLBACK *cb; + + if ((obj = obj_list_get_obj(&tpm_list, hTpm)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + tpm = (struct tr_tpm_obj *)obj->data; + + if ((cb = calloc_tspi(obj->tspContext, sizeof(TSS_CALLBACK))) == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(TSS_CALLBACK)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + switch (flag) { + case TSS_TSPATTRIB_TPM_CALLBACK_COLLATEIDENTITY: + cb->callback = tpm->Tspicb_CollateIdentity; + cb->appData = tpm->collateAppData; + cb->alg = tpm->collateAlg; + *size = sizeof(TSS_CALLBACK); + *out = (BYTE *)cb; + break; + case TSS_TSPATTRIB_TPM_CALLBACK_ACTIVATEIDENTITY: + cb->callback = tpm->Tspicb_ActivateIdentity; + cb->appData = tpm->activateAppData; + cb->alg = tpm->activateAlg; + *size = sizeof(TSS_CALLBACK); + *out = (BYTE *)cb; + break; + default: + free_tspi(obj->tspContext, cb); + result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } +done: + obj_list_put(&tpm_list); + + return result; +} + +void +obj_tpm_remove_policy_refs(TSS_HPOLICY hPolicy, TSS_HCONTEXT tspContext) +{ + struct tsp_object *obj; + struct obj_list *list = &tpm_list; + struct tr_tpm_obj *tpm; + + pthread_mutex_lock(&list->lock); + + for (obj = list->head; obj; obj = obj->next) { + if (obj->tspContext != tspContext) + continue; + + tpm = (struct tr_tpm_obj *)obj->data; + if (tpm->policy == hPolicy) + tpm->policy = NULL_HPOLICY; +#ifdef TSS_BUILD_TSS12 + if (tpm->operatorPolicy == hPolicy) + tpm->operatorPolicy = NULL_HPOLICY; +#endif + } + + pthread_mutex_unlock(&list->lock); +} + +#ifdef TSS_BUILD_COUNTER +TSS_RESULT +obj_tpm_get_current_counter(TSS_HTPM hTPM, TSS_COUNTER_ID *ctr_id) +{ + struct tsp_object *obj; + struct tr_tpm_obj *tpm; + TSS_RESULT result = TSS_SUCCESS; + UINT32 respLen, subCap = endian32(TPM_CAP_PROP_ACTIVE_COUNTER); + BYTE *resp; + + if ((obj = obj_list_get_obj(&tpm_list, hTPM)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + tpm = (struct tr_tpm_obj *)obj->data; + + if (tpm->ctr_id != 0xffffffff) { + *ctr_id = tpm->ctr_id; + goto done; + } + + /* No counter has yet been associated with the TPM object, so let the TPM object lock + * protect us here and get a counter ID */ + if ((result = TCS_API(obj->tspContext)->GetTPMCapability(obj->tspContext, TPM_CAP_PROPERTY, + sizeof(UINT32), (BYTE *)&subCap, + &respLen, &resp))) + goto done; + + if (respLen != sizeof(UINT32)) { + LogDebug("TPM GetCap response size isn't sizeof(UINT32)!"); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + memcpy(&tpm->ctr_id, resp, respLen); + free(resp); + + if (tpm->ctr_id == 0xffffffff) { + result = TSPERR(TSS_E_NO_ACTIVE_COUNTER); + goto done; + } + *ctr_id = tpm->ctr_id; +done: + obj_list_put(&tpm_list); + + return result; +} +#endif + diff --git a/src/tspi/ps/ps_utils.c b/src/tspi/ps/ps_utils.c new file mode 100644 index 0000000..aac40a1 --- /dev/null +++ b/src/tspi/ps/ps_utils.c @@ -0,0 +1,57 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> + +#include "trousers/tss.h" +#include "trousers_types.h" +#include "tcs_tsp.h" +#include "spi_utils.h" +#include "tspps.h" +#include "tsplog.h" + +inline TSS_RESULT +read_data(int fd, void *data, UINT32 size) +{ + int rc; + + rc = read(fd, data, size); + if (rc == -1) { + LogError("read of %d bytes: %s", size, strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } else if ((unsigned)rc != size) { + LogError("read of %d bytes (only %d read)", size, rc); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + return TSS_SUCCESS; +} + +inline TSS_RESULT +write_data(int fd, void *data, UINT32 size) +{ + int rc; + + rc = write(fd, data, size); + if (rc == -1) { + LogError("write of %d bytes: %s", size, strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } else if ((unsigned)rc != size) { + LogError("write of %d bytes (only %d written)", size, rc); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + return TSS_SUCCESS; +} diff --git a/src/tspi/ps/tspps.c b/src/tspi/ps/tspps.c new file mode 100644 index 0000000..56eb936 --- /dev/null +++ b/src/tspi/ps/tspps.c @@ -0,0 +1,1298 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <pwd.h> +#include <sys/types.h> +#include <sys/file.h> +#include <sys/stat.h> +#include <assert.h> +#include <fcntl.h> +#include <limits.h> +#include <netdb.h> +#if defined (HAVE_BYTEORDER_H) +#include <sys/byteorder.h> +#elif defined(HTOLE_DEFINED) +#include <endian.h> +#define LE_16 htole16 +#define LE_32 htole32 +#define LE_64 htole64 +#else +#define LE_16(x) (x) +#define LE_32(x) (x) +#define LE_64(x) (x) +#endif + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "tcs_tsp.h" +#include "spi_utils.h" +#include "tspps.h" +#include "tsplog.h" + +static int user_ps_fd = -1; +static MUTEX_DECLARE_INIT(user_ps_lock); +#if (defined (__FreeBSD__) || defined (__OpenBSD__)) +static MUTEX_DECLARE_INIT(user_ps_path); +#endif +static struct flock fl; + + +/* + * Determine the default path to the persistent storage file and create it if it doesn't exist. + */ +TSS_RESULT +get_user_ps_path(char **file) +{ + TSS_RESULT result; + char *file_name = NULL, *home_dir = NULL; + struct passwd *pwp; +#if (defined (__linux) || defined (linux) || defined(__GLIBC__)) + struct passwd pw; +#endif + struct stat stat_buf; + char buf[PASSWD_BUFSIZE]; + uid_t euid; + int rc; + + if ((file_name = getenv("TSS_USER_PS_FILE"))) { + *file = strdup(file_name); + return (*file) ? TSS_SUCCESS : TSPERR(TSS_E_OUTOFMEMORY); + } +#if (defined (__FreeBSD__) || defined (__OpenBSD__)) + MUTEX_LOCK(user_ps_path); +#endif + + euid = geteuid(); + +#if defined (SOLARIS) + /* + * Solaris keeps user PS in a local directory instead of + * in the user's home directory, which may be shared + * by multiple systems. + * + * The directory path on Solaris is /var/tpm/userps/[EUID]/ + */ + rc = snprintf(buf, sizeof (buf), "%s/%d", TSS_USER_PS_DIR, euid); +#else + setpwent(); + while (1) { +#if (defined (__linux) || defined (linux) || defined(__GLIBC__)) + rc = getpwent_r(&pw, buf, PASSWD_BUFSIZE, &pwp); + if (rc) { + LogDebugFn("USER PS: Error getting path to home directory: getpwent_r: %s", + strerror(rc)); + endpwent(); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + +#elif (defined (__FreeBSD__) || defined (__OpenBSD__)) + if ((pwp = getpwent()) == NULL) { + LogDebugFn("USER PS: Error getting path to home directory: getpwent: %s", + strerror(rc)); + endpwent(); + MUTEX_UNLOCK(user_ps_path); + return TSPERR(TSS_E_INTERNAL_ERROR); + } +#endif + if (euid == pwp->pw_uid) { + home_dir = strdup(pwp->pw_dir); + break; + } + } + endpwent(); + + if (!home_dir) + return TSPERR(TSS_E_OUTOFMEMORY); + + /* Tack on TSS_USER_PS_DIR and see if it exists */ + rc = snprintf(buf, sizeof (buf), "%s/%s", home_dir, TSS_USER_PS_DIR); +#endif /* SOLARIS */ + if (rc == sizeof (buf)) { + LogDebugFn("USER PS: Path to file too long! (> %d bytes)", PASSWD_BUFSIZE); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + errno = 0; + if ((rc = stat(buf, &stat_buf)) == -1) { + if (errno == ENOENT) { + errno = 0; + /* Create the user's ps directory if it is not there. */ + if ((rc = mkdir(buf, 0700)) == -1) { + LogDebugFn("USER PS: Error creating dir: %s: %s", buf, + strerror(errno)); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } else { + LogDebugFn("USER PS: Error stating dir: %s: %s", buf, strerror(errno)); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + + /* Directory exists or has been created, return the path to the file */ +#if defined (SOLARIS) + rc = snprintf(buf, sizeof (buf), "%s/%d/%s", TSS_USER_PS_DIR, euid, + TSS_USER_PS_FILE); +#else + rc = snprintf(buf, sizeof (buf), "%s/%s/%s", home_dir, TSS_USER_PS_DIR, + TSS_USER_PS_FILE); +#endif + if (rc == sizeof (buf)) { + LogDebugFn("USER PS: Path to file too long! (> %zd bytes)", sizeof (buf)); + } else + *file = strdup(buf); + + result = (*file) ? TSS_SUCCESS : TSPERR(TSS_E_OUTOFMEMORY); +done: + free(home_dir); + return result; +} + +TSS_RESULT +get_file(int *fd) +{ + TSS_RESULT result; + int rc = 0; + char *file_name = NULL; + + MUTEX_LOCK(user_ps_lock); + + /* check the global file handle first. If it exists, lock it and return */ + if (user_ps_fd != -1) { + fl.l_type = F_WRLCK; + if ((rc = fcntl(user_ps_fd, F_SETLKW, &fl))) { + LogDebug("USER PS: failed to lock file: %s", strerror(errno)); + MUTEX_UNLOCK(user_ps_lock); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + *fd = user_ps_fd; + return TSS_SUCCESS; + } + + /* open and lock the file */ + if ((result = get_user_ps_path(&file_name))) { + LogDebugFn("USER PS: error getting file path"); + MUTEX_UNLOCK(user_ps_lock); + return result; + } + + user_ps_fd = open(file_name, O_CREAT|O_RDWR, 0600); + if (user_ps_fd < 0) { + LogDebug("USER PS: open of %s failed: %s", file_name, strerror(errno)); + free(file_name); + MUTEX_UNLOCK(user_ps_lock); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + fl.l_type = F_WRLCK; + if ((rc = fcntl(user_ps_fd, F_SETLKW, &fl))) { + LogDebug("USER PS: failed to get lock of %s: %s", file_name, strerror(errno)); + free(file_name); + close(user_ps_fd); + user_ps_fd = -1; + MUTEX_UNLOCK(user_ps_lock); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + *fd = user_ps_fd; + free(file_name); + return TSS_SUCCESS; +} + +int +put_file(int fd) +{ + int rc = 0; + + fsync(fd); + + /* release the file lock */ + fl.l_type = F_UNLCK; + if ((rc = fcntl(fd, F_SETLKW, &fl))) { + LogDebug("USER PS: failed to unlock file: %s", strerror(errno)); + rc = -1; + } + + MUTEX_UNLOCK(user_ps_lock); + return rc; +} + +void +psfile_close(int fd) +{ + close(fd); + user_ps_fd = -1; + MUTEX_UNLOCK(user_ps_lock); +} + +TSS_RESULT +psfile_is_key_registered(int fd, TSS_UUID *uuid, TSS_BOOL *answer) +{ + TSS_RESULT result; + struct key_disk_cache tmp; + + if ((result = psfile_get_cache_entry_by_uuid(fd, uuid, &tmp)) == TSS_SUCCESS) + *answer = TRUE; + else if (result == (TSS_E_PS_KEY_NOTFOUND | TSS_LAYER_TSP)) + *answer = FALSE; + else + return result; + + return TSS_SUCCESS; +} + +TSS_RESULT +psfile_get_parent_uuid_by_uuid(int fd, TSS_UUID *uuid, TSS_UUID *ret_uuid) +{ + TSS_RESULT result; + struct key_disk_cache tmp; + + if ((result = psfile_get_cache_entry_by_uuid(fd, uuid, &tmp))) + return result; + + memcpy(ret_uuid, &tmp.parent_uuid, sizeof(TSS_UUID)); + + return TSS_SUCCESS; +} + +TSS_RESULT +psfile_get_parent_ps_type(int fd, TSS_UUID *uuid, UINT32 *type) +{ + TSS_RESULT result; + struct key_disk_cache tmp; + + if ((result = psfile_get_cache_entry_by_uuid(fd, uuid, &tmp))) + return result; + + if (tmp.flags & CACHE_FLAG_PARENT_PS_SYSTEM) + *type = TSS_PS_TYPE_SYSTEM; + else + *type = TSS_PS_TYPE_USER; + + return TSS_SUCCESS; +} + +/* + * return a key struct from PS given a uuid + */ +TSS_RESULT +psfile_get_key_by_uuid(int fd, TSS_UUID *uuid, BYTE *key) +{ + int rc; + TSS_RESULT result; + off_t file_offset; + struct key_disk_cache tmp; + BYTE buf[4096]; + + if ((result = psfile_get_cache_entry_by_uuid(fd, uuid, &tmp))) + return result; + + /* jump to the location of the key blob */ + file_offset = TSSPS_BLOB_DATA_OFFSET(&tmp); + + rc = lseek(fd, file_offset, SEEK_SET); + if (rc == ((off_t)-1)) { + LogDebugFn("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + if (tmp.blob_size > 4096) { + LogError("Blob size greater than 4096! Size: %d", + tmp.blob_size); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if ((rc = read_data(fd, buf, tmp.blob_size))) { + LogDebugFn("Blob read from disk failed."); + return rc; + } + + memcpy(key, buf, tmp.blob_size); + return TSS_SUCCESS; +} + +/* + * return a key struct from PS given a public key + */ +TSS_RESULT +psfile_get_key_by_pub(int fd, TSS_UUID *uuid, UINT32 pub_size, BYTE *pub, BYTE *key) +{ + int rc; + TSS_RESULT result; + off_t file_offset; + struct key_disk_cache tmp; + BYTE buf[4096]; + + if ((result = psfile_get_cache_entry_by_pub(fd, pub_size, pub, &tmp))) + return result; + + /* jump to the location of the key blob */ + file_offset = TSSPS_BLOB_DATA_OFFSET(&tmp); + + rc = lseek(fd, file_offset, SEEK_SET); + if (rc == ((off_t)-1)) { + LogDebugFn("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + if (tmp.blob_size > 4096) { + LogError("Blob size greater than 4096! Size: %d", + tmp.blob_size); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + if ((result = read_data(fd, buf, tmp.blob_size))) { + LogDebugFn("Blob read from disk failed."); + return result; + } + + memcpy(key, buf, tmp.blob_size); + memcpy(uuid, &tmp.uuid, sizeof(TSS_UUID)); + + return TSS_SUCCESS; +} + +TSS_RESULT +psfile_get_uuid_by_pub(int fd, UINT32 pub_size, BYTE *pub, TSS_UUID *uuid) +{ + TSS_RESULT result; + struct key_disk_cache tmp; + + if ((result = psfile_get_cache_entry_by_pub(fd, pub_size, pub, &tmp))) + return result; + + memcpy(uuid, &tmp.uuid, sizeof(TSS_UUID)); + + return TSS_SUCCESS; +} + +TSS_RESULT +psfile_change_num_keys(int fd, BYTE increment) +{ + int rc; + TSS_RESULT result; + UINT32 num_keys; + + rc = lseek(fd, TSSPS_NUM_KEYS_OFFSET, SEEK_SET); + if (rc == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + rc = read(fd, &num_keys, sizeof(UINT32)); + if (rc != sizeof(UINT32)) { + LogDebug("read of %zd bytes: %s", sizeof(UINT32), strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + num_keys = LE_32(num_keys); + + if (increment) + num_keys++; + else + num_keys--; + + rc = lseek(fd, TSSPS_NUM_KEYS_OFFSET, SEEK_SET); + if (rc == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + num_keys = LE_32(num_keys); + if ((result = write_data(fd, (void *)&num_keys, sizeof(UINT32)))) { + LogDebug("%s", __FUNCTION__); + return result; + } + + return TSS_SUCCESS; +} + +/* Write the initial header (number of keys and PS version) to initialize a new file */ +TSS_RESULT +psfile_write_key_header(int fd) +{ + int rc; + TSS_RESULT result; + UINT32 i; + + rc = lseek(fd, TSSPS_VERSION_OFFSET, SEEK_SET); + if (rc == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + i = TSSPS_VERSION; + if ((result = write_data(fd, &i, sizeof(BYTE)))) { + LogDebug("%s", __FUNCTION__); + return result; + } + + rc = lseek(fd, TSSPS_NUM_KEYS_OFFSET, SEEK_SET); + if (rc == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + i = 0; + if ((result = write_data(fd, &i, sizeof(UINT32)))) { + LogDebug("%s", __FUNCTION__); + return result; + } + + return TSS_SUCCESS; +} + +/* + * disk store format: + * + * TrouSerS 0.2.1+ + * Version 1: cached? + * [BYTE PS version = '\1'] + * [UINT32 num_keys_on_disk ] + * [TSS_UUID uuid0 ] yes + * [TSS_UUID uuid_parent0 ] yes + * [UINT16 pub_data_size0 ] yes + * [UINT16 blob_size0 ] yes + * [UINT32 vendor_data_size0] yes + * [UINT16 cache_flags0 ] yes + * [BYTE[] pub_data0 ] + * [BYTE[] blob0 ] + * [BYTE[] vendor_data0 ] + * [...] + * + */ +TSS_RESULT +psfile_write_key(int fd, + TSS_UUID *uuid, + TSS_UUID *parent_uuid, + UINT32 parent_ps, + BYTE *key_blob, + UINT16 key_blob_size) +{ + TSS_RESULT result; + TSS_KEY key; + UINT32 zero = 0; + UINT64 offset; + UINT16 pub_key_size, cache_flags = 0; + struct stat stat_buf; + int rc, file_offset; + + /* leaving the cache flag for parent ps type as 0 implies TSS_PS_TYPE_USER */ + if (parent_ps == TSS_PS_TYPE_SYSTEM) + cache_flags |= CACHE_FLAG_PARENT_PS_SYSTEM; + + if ((rc = fstat(fd, &stat_buf)) == -1) { + LogDebugFn("stat failed: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + file_offset = stat_buf.st_size; + + if (file_offset < (int)TSSPS_KEYS_OFFSET) { + if ((result = psfile_write_key_header(fd))) + return result; + file_offset = TSSPS_KEYS_OFFSET; + } + + rc = lseek(fd, file_offset, SEEK_SET); + if (rc == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + /* Unload the blob to get the public key */ + offset = 0; + if ((result = UnloadBlob_TSS_KEY(&offset, key_blob, &key))) + return result; + + pub_key_size = key.pubKey.keyLength; + + /* [TSS_UUID uuid0 ] yes */ + if ((result = write_data(fd, (void *)uuid, sizeof(TSS_UUID)))) { + LogDebug("%s", __FUNCTION__); + goto done; + } + + /* [TSS_UUID uuid_parent0 ] yes */ + if ((result = write_data(fd, (void *)parent_uuid, sizeof(TSS_UUID)))) { + LogDebug("%s", __FUNCTION__); + goto done; + } + + /* [UINT16 pub_data_size0 ] yes */ + pub_key_size = LE_16(pub_key_size); + if ((result = write_data(fd, &pub_key_size, sizeof(UINT16)))) { + LogDebug("%s", __FUNCTION__); + goto done; + } + pub_key_size = LE_16(pub_key_size); + + /* [UINT16 blob_size0 ] yes */ + key_blob_size = LE_16(key_blob_size); + if ((result = write_data(fd, &key_blob_size, sizeof(UINT16)))) { + LogDebug("%s", __FUNCTION__); + goto done; + } + key_blob_size = LE_16(key_blob_size); + + /* [UINT32 vendor_data_size0 ] yes */ + if ((result = write_data(fd, &zero, sizeof(UINT32)))) { + LogDebug("%s", __FUNCTION__); + goto done; + } + + /* [UINT16 cache_flags0 ] yes */ + cache_flags = LE_16(cache_flags); + if ((result = write_data(fd, &cache_flags, sizeof(UINT16)))) { + LogDebug("%s", __FUNCTION__); + goto done; + } + cache_flags = LE_16(cache_flags); + + /* [BYTE[] pub_data0 ] no */ + if ((result = write_data(fd, (void *)key.pubKey.key, pub_key_size))) { + LogDebug("%s", __FUNCTION__); + goto done; + } + + /* [BYTE[] blob0 ] no */ + if ((result = write_data(fd, (void *)key_blob, key_blob_size))) { + LogDebug("%s", __FUNCTION__); + goto done; + } + + if ((result = psfile_change_num_keys(fd, TSS_PSFILE_INCREMENT_NUM_KEYS))) { + LogDebug("%s", __FUNCTION__); + goto done; + } + +done: + free_key_refs(&key); + return result; +} + +TSS_RESULT +psfile_remove_key(int fd, TSS_UUID *uuid) +{ + TSS_RESULT result; + UINT32 head_offset = 0, tail_offset; + int rc, size = 0; + struct key_disk_cache c; + BYTE buf[4096]; + + if ((result = psfile_get_cache_entry_by_uuid(fd, uuid, &c))) + return result; + + /* head_offset is the offset the beginning of the key */ + head_offset = TSSPS_UUID_OFFSET(&c); + + /* tail_offset is the offset the beginning of the next key */ + tail_offset = TSSPS_VENDOR_DATA_OFFSET(&c) + c.vendor_data_size; + + rc = lseek(fd, tail_offset, SEEK_SET); + if (rc == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + /* read in from tail, write out to head to fill the gap */ + while ((rc = read(fd, buf, sizeof(buf))) > 0) { + size = rc; + tail_offset += size; + + /* set the file pointer to where we want to write */ + rc = lseek(fd, head_offset, SEEK_SET); + if (rc == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + /* write the data */ + if ((result = write_data(fd, (void *)buf, size))) { + LogDebug("%s", __FUNCTION__); + return result; + } + head_offset += size; + + /* set the file pointer to where we want to read in the next + * loop */ + rc = lseek(fd, tail_offset, SEEK_SET); + if (rc == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + } + + if (rc < 0) { + LogDebug("read: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + /* set the file pointer to where we want to write */ + rc = lseek(fd, head_offset, SEEK_SET); + if (rc == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + /* head_offset now contains a pointer to where we want to truncate the + * file. Zero out the old tail end of the file and truncate it. */ + + memset(buf, 0, sizeof(buf)); + + /* Zero out the old tail end of the file */ + if ((result = write_data(fd, (void *)buf, tail_offset - head_offset))) { + LogDebug("%s", __FUNCTION__); + return result; + } + + if ((rc = ftruncate(fd, head_offset)) < 0) { + LogDebug("ftruncate: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + /* we succeeded in removing a key from the disk. Decrement the number + * of keys in the file */ + if ((result = psfile_change_num_keys(fd, TSS_PSFILE_DECREMENT_NUM_KEYS))) + return result; + + return TSS_SUCCESS; +} + +TSS_RESULT +psfile_get_all_cache_entries(int fd, UINT32 *size, struct key_disk_cache **c) +{ + UINT32 i, num_keys = psfile_get_num_keys(fd); + int offset; + TSS_RESULT result; + struct key_disk_cache *tmp = NULL; + + if (num_keys == 0) { + *size = 0; + *c = NULL; + return TSS_SUCCESS; + } + + /* make sure the file pointer is where we expect, just after the number + * of keys on disk at the head of the file + */ + offset = lseek(fd, TSSPS_KEYS_OFFSET, SEEK_SET); + if (offset == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + if ((tmp = malloc(num_keys * sizeof(struct key_disk_cache))) == NULL) { + LogDebug("malloc of %zu bytes failed.", num_keys * sizeof(struct key_disk_cache)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + for (i = 0; i < num_keys; i++) { + offset = lseek(fd, 0, SEEK_CUR); + if (offset == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto err_exit; + } + tmp[i].offset = offset; + + /* read UUID */ + if ((result = read_data(fd, &tmp[i].uuid, sizeof(TSS_UUID)))) { + LogDebug("%s", __FUNCTION__); + goto err_exit; + } + + /* read parent UUID */ + if ((result = read_data(fd, &tmp[i].parent_uuid, sizeof(TSS_UUID)))) { + LogDebug("%s", __FUNCTION__); + goto err_exit; + } + + /* pub data size */ + if ((result = read_data(fd, &tmp[i].pub_data_size, sizeof(UINT16)))) { + LogDebug("%s", __FUNCTION__); + goto err_exit; + } + tmp[i].pub_data_size = LE_16(tmp[i].pub_data_size); + + DBG_ASSERT(tmp[i].pub_data_size <= 2048); + + /* blob size */ + if ((result = read_data(fd, &tmp[i].blob_size, sizeof(UINT16)))) { + LogDebug("%s", __FUNCTION__); + goto err_exit; + } + tmp[i].blob_size = LE_16(tmp[i].blob_size); + + DBG_ASSERT(tmp[i].blob_size <= 4096); + + /* vendor data size */ + if ((result = read_data(fd, &tmp[i].vendor_data_size, sizeof(UINT32)))) { + LogDebug("%s", __FUNCTION__); + goto err_exit; + } + tmp[i].vendor_data_size = LE_32(tmp[i].vendor_data_size); + + /* cache flags */ + if ((result = read_data(fd, &tmp[i].flags, sizeof(UINT16)))) { + LogDebug("%s", __FUNCTION__); + goto err_exit; + } + tmp[i].flags = LE_16(tmp[i].flags); + + /* fast forward over the pub key */ + offset = lseek(fd, tmp[i].pub_data_size, SEEK_CUR); + if (offset == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto err_exit; + } + + /* fast forward over the blob */ + offset = lseek(fd, tmp[i].blob_size, SEEK_CUR); + if (offset == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto err_exit; + } + + /* ignore vendor data for user ps */ + } + + *size = num_keys; + *c = tmp; + + return TSS_SUCCESS; + +err_exit: + free(tmp); + return result; +} + +TSS_RESULT +copy_key_info(int fd, TSS_KM_KEYINFO *ki, struct key_disk_cache *c) +{ + TSS_KEY key; + BYTE blob[4096]; + UINT64 offset; + TSS_RESULT result; + off_t off; + + /* Set the file pointer to the offset that the key blob is at */ + off = lseek(fd, TSSPS_BLOB_DATA_OFFSET(c), SEEK_SET); + if (off == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + /* Read in the key blob */ + if ((result = read_data(fd, (void *)blob, c->blob_size))) { + LogDebug("%s", __FUNCTION__); + return result; + } + + /* Expand the blob into a useable form */ + offset = 0; + if ((result = UnloadBlob_TSS_KEY(&offset, blob, &key))) + return result; + + if (key.hdr.key12.tag == TPM_TAG_KEY12) { + ki->versionInfo.bMajor = TSS_SPEC_MAJOR; + ki->versionInfo.bMinor = TSS_SPEC_MINOR; + ki->versionInfo.bRevMajor = 0; + ki->versionInfo.bRevMinor = 0; + } else + memcpy(&ki->versionInfo, &key.hdr.key11.ver, sizeof(TSS_VERSION)); + memcpy(&ki->keyUUID, &c->uuid, sizeof(TSS_UUID)); + memcpy(&ki->parentKeyUUID, &c->parent_uuid, sizeof(TSS_UUID)); + ki->bAuthDataUsage = key.authDataUsage; + + free_key_refs(&key); + + return TSS_SUCCESS; +} + +TSS_RESULT +copy_key_info2(int fd, TSS_KM_KEYINFO2 *ki, struct key_disk_cache *c) +{ + TSS_KEY key; + BYTE blob[4096]; + UINT64 offset; + TSS_RESULT result; + off_t off; + + /* Set the file pointer to the offset that the key blob is at */ + off = lseek(fd, TSSPS_BLOB_DATA_OFFSET(c), SEEK_SET); + if (off == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + /* Read in the key blob */ + if ((result = read_data(fd, (void *)blob, c->blob_size))) { + LogDebug("%s", __FUNCTION__); + return result; + } + + /* Expand the blob into a useable form */ + offset = 0; + if ((result = UnloadBlob_TSS_KEY(&offset, blob, &key))) + return result; + + if (key.hdr.key12.tag == TPM_TAG_KEY12) { + ki->versionInfo.bMajor = TSS_SPEC_MAJOR; + ki->versionInfo.bMinor = TSS_SPEC_MINOR; + ki->versionInfo.bRevMajor = 0; + ki->versionInfo.bRevMinor = 0; + } else + memcpy(&ki->versionInfo, &key.hdr.key11.ver, sizeof(TSS_VERSION)); + memcpy(&ki->keyUUID, &c->uuid, sizeof(TSS_UUID)); + memcpy(&ki->parentKeyUUID, &c->parent_uuid, sizeof(TSS_UUID)); + + /* CHECK: fill the two new fields of TSS_KM_KEYINFO2 */ + ki->persistentStorageType = TSS_PS_TYPE_USER; + ki->persistentStorageTypeParent = c->flags & CACHE_FLAG_PARENT_PS_SYSTEM ? + TSS_PS_TYPE_SYSTEM : TSS_PS_TYPE_USER; + + ki->bAuthDataUsage = key.authDataUsage; + + free_key_refs(&key); + + return TSS_SUCCESS; +} + + +TSS_RESULT +psfile_get_registered_keys(int fd, + TSS_UUID *uuid, + TSS_UUID *tcs_uuid, + UINT32 *size, + TSS_KM_KEYINFO **keys) +{ + TSS_RESULT result; + struct key_disk_cache *cache_entries; + UINT32 cache_size, i, j; + TSS_KM_KEYINFO *keyinfos = NULL; + TSS_UUID *find_uuid; + + if ((result = psfile_get_all_cache_entries(fd, &cache_size, &cache_entries))) + return result; + + if (cache_size == 0) { + if (uuid) + return TSPERR(TSS_E_PS_KEY_NOTFOUND); + else { + *size = 0; + *keys = NULL; + return TSS_SUCCESS; + } + } + + if (uuid) { + find_uuid = uuid; + j = 0; + +restart_search: + /* Search for the requested UUID. When found, allocate new space for it, copy + * it in, then change the uuid to be searched for it its parent and start over. */ + for (i = 0; i < cache_size; i++) { + if (!memcmp(&cache_entries[i].uuid, find_uuid, sizeof(TSS_UUID))) { + if (!(keyinfos = realloc(keyinfos, + (j+1) * sizeof(TSS_KM_KEYINFO)))) { + free(cache_entries); + free(keyinfos); + return TSPERR(TSS_E_OUTOFMEMORY); + } + memset(&keyinfos[j], 0, sizeof(TSS_KM_KEYINFO)); + + if ((result = copy_key_info(fd, &keyinfos[j], &cache_entries[i]))) { + free(cache_entries); + free(keyinfos); + return result; + } + + find_uuid = &keyinfos[j].parentKeyUUID; + j++; + goto restart_search; + } + } + + /* Searching for keys in the user PS will always lead us up to some key in the + * system PS. Return that key's uuid so that the upper layers can call down to TCS + * to search for it. */ + memcpy(tcs_uuid, find_uuid, sizeof(TSS_UUID)); + + *size = j; + } else { + if ((keyinfos = calloc(cache_size, sizeof(TSS_KM_KEYINFO))) == NULL) { + LogDebug("malloc of %zu bytes failed.", + cache_size * sizeof(TSS_KM_KEYINFO)); + free(cache_entries); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + for (i = 0; i < cache_size; i++) { + if ((result = copy_key_info(fd, &keyinfos[i], &cache_entries[i]))) { + free(cache_entries); + free(keyinfos); + return result; + } + } + + *size = cache_size; + } + + free(cache_entries); + + *keys = keyinfos; + + return TSS_SUCCESS; +} + +TSS_RESULT +psfile_get_registered_keys2(int fd, + TSS_UUID *uuid, + TSS_UUID *tcs_uuid, + UINT32 *size, + TSS_KM_KEYINFO2 **keys) +{ + TSS_RESULT result; + struct key_disk_cache *cache_entries; + UINT32 cache_size, i, j; + TSS_KM_KEYINFO2 *keyinfos = NULL; + TSS_UUID *find_uuid; + + if ((result = psfile_get_all_cache_entries(fd, &cache_size, &cache_entries))) + return result; + + if (cache_size == 0) { + if (uuid) + return TSPERR(TSS_E_PS_KEY_NOTFOUND); + else { + *size = 0; + *keys = NULL; + return TSS_SUCCESS; + } + } + + if (uuid) { + find_uuid = uuid; + j = 0; + + restart_search: + /* Search for the requested UUID. When found, allocate new space for it, copy + * it in, then change the uuid to be searched for it its parent and start over. */ + for (i = 0; i < cache_size; i++) { + /*Return 0 if normal finish*/ + if (!memcmp(&cache_entries[i].uuid, find_uuid, sizeof(TSS_UUID))) { + if (!(keyinfos = realloc(keyinfos, + (j+1) * sizeof(TSS_KM_KEYINFO2)))) { + free(cache_entries); + free(keyinfos); + return TSPERR(TSS_E_OUTOFMEMORY); + } + /* Here the key UUID is found and needs to be copied for the array*/ + /* Initializes the keyinfos with 0's*/ + memset(&keyinfos[j], 0, sizeof(TSS_KM_KEYINFO2)); + + if ((result = copy_key_info2(fd, &keyinfos[j], &cache_entries[i]))) { + free(cache_entries); + free(keyinfos); + return result; + } + + find_uuid = &keyinfos[j].parentKeyUUID; + j++; + goto restart_search; + } + } + + /* Searching for keys in the user PS will always lead us up to some key in the + * system PS. Return that key's uuid so that the upper layers can call down to TCS + * to search for it. */ + memcpy(tcs_uuid, find_uuid, sizeof(TSS_UUID)); + + *size = j; + } else { + if ((keyinfos = calloc(cache_size, sizeof(TSS_KM_KEYINFO2))) == NULL) { + LogDebug("malloc of %zu bytes failed.", + cache_size * sizeof(TSS_KM_KEYINFO2)); + free(cache_entries); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + for (i = 0; i < cache_size; i++) { + if ((result = copy_key_info2(fd, &keyinfos[i], &cache_entries[i]))) { + free(cache_entries); + free(keyinfos); + return result; + } + } + + *size = cache_size; + } + + free(cache_entries); + + *keys = keyinfos; + + return TSS_SUCCESS; +} + +/* + * read into the PS file and return the number of keys + */ +UINT32 +psfile_get_num_keys(int fd) +{ + UINT32 num_keys; + int rc; + + /* go to the number of keys */ + rc = lseek(fd, TSSPS_NUM_KEYS_OFFSET, SEEK_SET); + if (rc == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return 0; + } + + rc = read(fd, &num_keys, sizeof(UINT32)); + if (rc < 0) { + LogDebug("read of %zd bytes: %s", sizeof(UINT32), strerror(errno)); + return 0; + } else if ((unsigned)rc < sizeof(UINT32)) { + num_keys = 0; + } + + /* The system PS file is written in little-endian */ + num_keys = LE_32(num_keys); + return num_keys; +} + +/* + * disk store format: + * + * TrouSerS 0.2.1+ + * Version 1: cached? + * [BYTE PS version = '\1'] + * [UINT32 num_keys_on_disk ] + * [TSS_UUID uuid0 ] yes + * [TSS_UUID uuid_parent0 ] yes + * [UINT16 pub_data_size0 ] yes + * [UINT16 blob_size0 ] yes + * [UINT32 vendor_data_size0] yes + * [UINT16 cache_flags0 ] yes + * [BYTE[] pub_data0 ] + * [BYTE[] blob0 ] + * [BYTE[] vendor_data0 ] + * [...] + * + */ +TSS_RESULT +psfile_get_cache_entry_by_uuid(int fd, TSS_UUID *uuid, struct key_disk_cache *c) +{ + UINT32 i, num_keys = psfile_get_num_keys(fd); + int offset; + TSS_RESULT result; + BYTE found = 0; + + if (num_keys == 0) + return TSPERR(TSS_E_PS_KEY_NOTFOUND); + + /* make sure the file pointer is where we expect, just after the number + * of keys on disk at the head of the file + */ + offset = lseek(fd, TSSPS_KEYS_OFFSET, SEEK_SET); + if (offset == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + for (i = 0; i < num_keys && !found; i++) { + offset = lseek(fd, 0, SEEK_CUR); + if (offset == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + c->offset = offset; + + /* read UUID */ + if ((result = read_data(fd, (void *)&c->uuid, sizeof(TSS_UUID)))) { + LogDebug("%s", __FUNCTION__); + return result; + } + + if (!memcmp(&c->uuid, uuid, sizeof(TSS_UUID))) { + found = 1; + + /* read parent UUID */ + if ((result = read_data(fd, (void *)&c->parent_uuid, sizeof(TSS_UUID)))) { + LogDebug("%s", __FUNCTION__); + return result; + } + } else { + /* fast forward over the parent UUID */ + offset = lseek(fd, sizeof(TSS_UUID), SEEK_CUR); + if (offset == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + } + + /* pub data size */ + if ((result = read_data(fd, &c->pub_data_size, sizeof(UINT16)))) { + LogDebug("%s", __FUNCTION__); + return result; + } + c->pub_data_size = LE_16(c->pub_data_size); + DBG_ASSERT(c->pub_data_size <= 2048 && c->pub_data_size > 0); + + /* blob size */ + if ((result = read_data(fd, &c->blob_size, sizeof(UINT16)))) { + LogDebug("%s", __FUNCTION__); + return result; + } + c->blob_size = LE_16(c->blob_size); + DBG_ASSERT(c->blob_size <= 4096 && c->blob_size > 0); + + /* vendor data size */ + if ((result = read_data(fd, &c->vendor_data_size, sizeof(UINT32)))) { + LogDebug("%s", __FUNCTION__); + return result; + } + c->vendor_data_size = LE_32(c->vendor_data_size); + + /* cache flags */ + if ((result = read_data(fd, &c->flags, sizeof(UINT16)))) { + LogDebug("%s", __FUNCTION__); + return result; + } + c->flags = LE_16(c->flags); + + /* fast forward over the pub key */ + offset = lseek(fd, c->pub_data_size, SEEK_CUR); + if (offset == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + /* fast forward over the blob */ + offset = lseek(fd, c->blob_size, SEEK_CUR); + if (offset == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + /* ignore vendor data in user ps */ + } + + return found ? TSS_SUCCESS : TSPERR(TSS_E_PS_KEY_NOTFOUND); +} + +TSS_RESULT +psfile_get_cache_entry_by_pub(int fd, UINT32 pub_size, BYTE *pub, struct key_disk_cache *c) +{ + BYTE blob[2048]; + UINT32 i, num_keys = psfile_get_num_keys(fd); + int offset; + TSS_RESULT result; + + if (num_keys == 0) + return TSPERR(TSS_E_PS_KEY_NOTFOUND); + + /* make sure the file pointer is where we expect, just after the number + * of keys on disk at the head of the file + */ + offset = lseek(fd, TSSPS_KEYS_OFFSET, SEEK_SET); + if (offset == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + for (i = 0; i < num_keys; i++) { + offset = lseek(fd, 0, SEEK_CUR); + if (offset == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + c->offset = offset; + + /* read UUID */ + if ((result = read_data(fd, (void *)&c->uuid, sizeof(TSS_UUID)))) { + LogDebug("%s", __FUNCTION__); + return result; + } + + /* read parent UUID */ + if ((result = read_data(fd, (void *)&c->parent_uuid, sizeof(TSS_UUID)))) { + LogDebug("%s", __FUNCTION__); + return result; + } + + /* pub data size */ + if ((result = read_data(fd, &c->pub_data_size, sizeof(UINT16)))) { + LogDebug("%s", __FUNCTION__); + return result; + } + + c->pub_data_size = LE_16(c->pub_data_size); + DBG_ASSERT(c->pub_data_size <= 2048 && c->pub_data_size > 0); + + /* blob size */ + if ((result = read_data(fd, &c->blob_size, sizeof(UINT16)))) { + LogDebug("%s", __FUNCTION__); + return result; + } + + c->blob_size = LE_16(c->blob_size); + DBG_ASSERT(c->blob_size <= 4096 && c->blob_size > 0); + + /* vendor data size */ + if ((result = read_data(fd, &c->vendor_data_size, sizeof(UINT32)))) { + LogDebug("%s", __FUNCTION__); + return result; + } + c->vendor_data_size = LE_32(c->vendor_data_size); + + /* cache flags */ + if ((result = read_data(fd, &c->flags, sizeof(UINT16)))) { + LogDebug("%s", __FUNCTION__); + return result; + } + c->flags = LE_16(c->flags); + + if (c->pub_data_size == pub_size) { + /* read in the pub key */ + if ((result = read_data(fd, blob, c->pub_data_size))) { + LogDebug("%s", __FUNCTION__); + return result; + } + + if (!memcmp(blob, pub, pub_size)) + break; + } + + /* fast forward over the blob */ + offset = lseek(fd, c->blob_size, SEEK_CUR); + if (offset == ((off_t)-1)) { + LogDebug("lseek: %s", strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + /* ignore vendor data */ + } + + return TSS_SUCCESS; +} diff --git a/src/tspi/rpc/hosttable.c b/src/tspi/rpc/hosttable.c new file mode 100644 index 0000000..f3ec2eb --- /dev/null +++ b/src/tspi/rpc/hosttable.c @@ -0,0 +1,182 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers_types.h" +#include "tsplog.h" +#include "hosttable.h" +#include "obj.h" + +struct host_table *ht = NULL; + +TSS_RESULT +host_table_init() +{ + ht = calloc(1, sizeof(struct host_table)); + if (ht == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(struct host_table)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + MUTEX_INIT(ht->lock); + + return TSS_SUCCESS; +} + +#ifdef SOLARIS +#pragma init(_init) +void _init(void) +#else +void __attribute__ ((constructor)) my_init(void) +#endif +{ + host_table_init(); + __tspi_obj_list_init(); +} + +void +host_table_final() +{ + struct host_table_entry *hte, *next = NULL; + + MUTEX_LOCK(ht->lock); + + for (hte = ht->entries; hte; hte = next) { + if (hte) + next = hte->next; + if (hte->hostname) + free(hte->hostname); + if (hte->comm.buf) + free(hte->comm.buf); + free(hte); + } + + MUTEX_UNLOCK(ht->lock); + + free(ht); + ht = NULL; +} + +#ifdef SOLARIS +#pragma fini(_fini) +void _fini(void) +#else +void __attribute__ ((destructor)) my_fini(void) +#endif +{ + host_table_final(); +} + +TSS_RESULT +__tspi_add_table_entry(TSS_HCONTEXT tspContext, BYTE *host, int type, struct host_table_entry **ret) +{ + struct host_table_entry *entry, *tmp; + + entry = calloc(1, sizeof(struct host_table_entry)); + if (entry == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(struct host_table_entry)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + entry->tspContext = tspContext; + entry->hostname = host; + entry->type = type; + entry->comm.buf_size = TCSD_INIT_TXBUF_SIZE; + entry->comm.buf = calloc(1, entry->comm.buf_size); + if (entry->comm.buf == NULL) { + LogError("malloc of %u bytes failed.", entry->comm.buf_size); + free(entry); + return TSPERR(TSS_E_OUTOFMEMORY); + } + MUTEX_INIT(entry->lock); + + MUTEX_LOCK(ht->lock); + + for (tmp = ht->entries; tmp; tmp = tmp->next) { + if (tmp->tspContext == tspContext) { + LogError("Tspi_Context_Connect attempted on an already connected context!"); + MUTEX_UNLOCK(ht->lock); + free(entry->hostname); + free(entry->comm.buf); + free(entry); + return TSPERR(TSS_E_CONNECTION_FAILED); + } + } + + if( ht->entries == NULL ) { + ht->entries = entry; + } else { + for (tmp = ht->entries; tmp->next; tmp = tmp->next) + ; + tmp->next = entry; + } + MUTEX_UNLOCK(ht->lock); + + *ret = entry; + + return TSS_SUCCESS; +} + +void +remove_table_entry(TSS_HCONTEXT tspContext) +{ + struct host_table_entry *hte, *prev = NULL; + + MUTEX_LOCK(ht->lock); + + for (hte = ht->entries; hte; prev = hte, hte = hte->next) { + if (hte->tspContext == tspContext) { + if (prev != NULL) + prev->next = hte->next; + else + ht->entries = hte->next; + if (hte->hostname) + free(hte->hostname); + free(hte->comm.buf); + free(hte); + break; + } + } + + MUTEX_UNLOCK(ht->lock); +} + +struct host_table_entry * +get_table_entry(TSS_HCONTEXT tspContext) +{ + struct host_table_entry *index = NULL; + + MUTEX_LOCK(ht->lock); + + for (index = ht->entries; index; index = index->next) { + if (index->tspContext == tspContext) + break; + } + + if (index) + MUTEX_LOCK(index->lock); + + MUTEX_UNLOCK(ht->lock); + + return index; +} + +void +put_table_entry(struct host_table_entry *entry) +{ + if (entry) + MUTEX_UNLOCK(entry->lock); +} + diff --git a/src/tspi/rpc/tcs_api.c b/src/tspi/rpc/tcs_api.c new file mode 100644 index 0000000..3eeb1fb --- /dev/null +++ b/src/tspi/rpc/tcs_api.c @@ -0,0 +1,3377 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004, 2007 + * + */ + + +#include <stdlib.h> +#include <syslog.h> +#include <unistd.h> + +#include "trousers/tss.h" +#include "trousers_types.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "hosttable.h" +#include "tsplog.h" +#include "rpc_tcstp_tsp.h" +#include "obj_context.h" + + +TSS_RESULT +RPC_Error(TSS_HCONTEXT tspContext, ...) +{ + LogDebugFn("Context: 0x%x", tspContext); + return TSPERR(TSS_E_INTERNAL_ERROR); +} + +TSS_RESULT +RPC_OpenContext(TSS_HCONTEXT tspContext, BYTE *hostname, int type) +{ + TSS_RESULT result; + TCS_CONTEXT_HANDLE tcsContext; + struct host_table_entry *entry; + UINT32 tpm_version; + + /* __tspi_add_table_entry() will make sure an entry doesn't already exist for this tsp context */ + if ((result = __tspi_add_table_entry(tspContext, hostname, type, &entry))) + return result; + + switch (type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + if ((result = RPC_OpenContext_TP(entry, &tpm_version, &tcsContext))) + remove_table_entry(tspContext); + else { + entry->tcsContext = tcsContext; + if (obj_context_set_tpm_version(tspContext, tpm_version)) { + remove_table_entry(tspContext); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + return result; + default: + break; + } + + return TSPERR(TSS_E_INTERNAL_ERROR); +} + +TSS_RESULT RPC_GetRegisteredKeyByPublicInfo(TSS_HCONTEXT tspContext, + TCPA_ALGORITHM_ID algID, /* in */ + UINT32 ulPublicInfoLength, /* in */ + BYTE * rgbPublicInfo, /* in */ + UINT32 * keySize, BYTE ** keyBlob) +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_GetRegisteredKeyByPublicInfo_TP(entry, algID, + ulPublicInfoLength, + rgbPublicInfo, keySize, + keyBlob); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_CloseContext(TSS_HCONTEXT tspContext) /* in */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + if ((result = RPC_CloseContext_TP(entry)) == TSS_SUCCESS) { + close(entry->socket); + remove_table_entry(tspContext); + } + break; + default: + break; + } + + if (result != TSS_SUCCESS) + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_FreeMemory(TSS_HCONTEXT tspContext, /* in */ + BYTE * pMemory) /* in */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_FreeMemory_TP(entry, pMemory); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_LogPcrEvent(TSS_HCONTEXT tspContext, /* in */ + TSS_PCR_EVENT Event, /* in */ + UINT32 * pNumber) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_LogPcrEvent_TP(entry, Event, pNumber); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_GetPcrEvent(TSS_HCONTEXT tspContext, /* in */ + UINT32 PcrIndex, /* in */ + UINT32 * pNumber, /* in, out */ + TSS_PCR_EVENT ** ppEvent) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = + RPC_GetPcrEvent_TP(entry, PcrIndex, pNumber, ppEvent); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_GetPcrEventsByPcr(TSS_HCONTEXT tspContext, /* in */ + UINT32 PcrIndex, /* in */ + UINT32 FirstEvent, /* in */ + UINT32 * pEventCount, /* in,out */ + TSS_PCR_EVENT ** ppEvents) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_GetPcrEventsByPcr_TP(entry, PcrIndex, FirstEvent, + pEventCount, ppEvents); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_GetPcrEventLog(TSS_HCONTEXT tspContext, /* in */ + UINT32 * pEventCount, /* out */ + TSS_PCR_EVENT ** ppEvents) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_GetPcrEventLog_TP(entry, pEventCount, ppEvents); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_RegisterKey(TSS_HCONTEXT tspContext, /* in */ + TSS_UUID WrappingKeyUUID, /* in */ + TSS_UUID KeyUUID, /* in */ + UINT32 cKeySize, /* in */ + BYTE * rgbKey, /* in */ + UINT32 cVendorData, /* in */ + BYTE * gbVendorData) /* in */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_RegisterKey_TP(entry, WrappingKeyUUID, KeyUUID, cKeySize, + rgbKey, cVendorData, gbVendorData); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_UnregisterKey(TSS_HCONTEXT tspContext, /* in */ + TSS_UUID KeyUUID) /* in */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_UnregisterKey_TP(entry, KeyUUID); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_EnumRegisteredKeys(TSS_HCONTEXT tspContext, /* in */ + TSS_UUID * pKeyUUID, /* in */ + UINT32 * pcKeyHierarchySize, /* out */ + TSS_KM_KEYINFO ** ppKeyHierarchy) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_EnumRegisteredKeys_TP(entry, pKeyUUID, pcKeyHierarchySize, + ppKeyHierarchy); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_EnumRegisteredKeys2(TSS_HCONTEXT tspContext, /* in */ + TSS_UUID * pKeyUUID, /* in */ + UINT32 * pcKeyHierarchySize, /* out */ + TSS_KM_KEYINFO2 ** ppKeyHierarchy) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_EnumRegisteredKeys2_TP(entry, pKeyUUID, pcKeyHierarchySize, + ppKeyHierarchy); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + + +TSS_RESULT RPC_GetRegisteredKey(TSS_HCONTEXT tspContext, /* in */ + TSS_UUID KeyUUID, /* in */ + TSS_KM_KEYINFO ** ppKeyInfo) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_GetRegisteredKey_TP(entry, KeyUUID, ppKeyInfo); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_GetRegisteredKeyBlob(TSS_HCONTEXT tspContext, /* in */ + TSS_UUID KeyUUID, /* in */ + UINT32 * pcKeySize, /* out */ + BYTE ** prgbKey) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_GetRegisteredKeyBlob_TP(entry, KeyUUID, pcKeySize, prgbKey); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_LoadKeyByBlob(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE hUnwrappingKey, /* in */ + UINT32 cWrappedKeyBlobSize, /* in */ + BYTE * rgbWrappedKeyBlob, /* in */ + TPM_AUTH * pAuth, /* in, out */ + TCS_KEY_HANDLE * phKeyTCSI, /* out */ + TCS_KEY_HANDLE * phKeyHMAC) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_LoadKeyByBlob_TP(entry, hUnwrappingKey, cWrappedKeyBlobSize, + rgbWrappedKeyBlob, pAuth, phKeyTCSI, + phKeyHMAC); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_LoadKeyByUUID(TSS_HCONTEXT tspContext, /* in */ + TSS_UUID KeyUUID, /* in */ + TCS_LOADKEY_INFO * pLoadKeyInfo, /* in, out */ + TCS_KEY_HANDLE * phKeyTCSI) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_LoadKeyByUUID_TP(entry, KeyUUID, pLoadKeyInfo, phKeyTCSI); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_EvictKey(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE hKey) /* in */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_EvictKey_TP(entry, hKey); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_CreateWrapKey(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE hWrappingKey, /* in */ + TCPA_ENCAUTH *KeyUsageAuth, /* in */ + TCPA_ENCAUTH *KeyMigrationAuth, /* in */ + UINT32 keyInfoSize, /* in */ + BYTE * keyInfo, /* in */ + UINT32 * keyDataSize, /* out */ + BYTE ** keyData, /* out */ + TPM_AUTH * pAuth) /* in, out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_CreateWrapKey_TP(entry, hWrappingKey, KeyUsageAuth, + KeyMigrationAuth, keyInfoSize, keyInfo, + keyDataSize, keyData, pAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_GetPubKey(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE hKey, /* in */ + TPM_AUTH * pAuth, /* in, out */ + UINT32 * pcPubKeySize, /* out */ + BYTE ** prgbPubKey) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_GetPubKey_TP(entry, hKey, pAuth, pcPubKeySize, prgbPubKey); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_MakeIdentity(TSS_HCONTEXT tspContext, /* in */ + TCPA_ENCAUTH identityAuth, /* in */ + TCPA_CHOSENID_HASH IDLabel_PrivCAHash, /* in */ + UINT32 idKeyInfoSize, /* in */ + BYTE * idKeyInfo, /* in */ + TPM_AUTH * pSrkAuth, /* in, out */ + TPM_AUTH * pOwnerAuth, /* in, out */ + UINT32 * idKeySize, /* out */ + BYTE ** idKey, /* out */ + UINT32 * pcIdentityBindingSize, /* out */ + BYTE ** prgbIdentityBinding, /* out */ + UINT32 * pcEndorsementCredentialSize, /* out */ + BYTE ** prgbEndorsementCredential, /* out */ + UINT32 * pcPlatformCredentialSize, /* out */ + BYTE ** prgbPlatformCredential, /* out */ + UINT32 * pcConformanceCredentialSize, /* out */ + BYTE ** prgbConformanceCredential) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_MakeIdentity_TP(entry, identityAuth, + IDLabel_PrivCAHash, idKeyInfoSize, idKeyInfo, + pSrkAuth, pOwnerAuth, idKeySize, idKey, + pcIdentityBindingSize, prgbIdentityBinding, + pcEndorsementCredentialSize, + prgbEndorsementCredential, + pcPlatformCredentialSize, + prgbPlatformCredential, + pcConformanceCredentialSize, + prgbConformanceCredential); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +#ifdef TSS_BUILD_TSS12 +TSS_RESULT RPC_GetCredential(TSS_HCONTEXT tspContext, /* in */ + UINT32 ulCredentialType, /* in */ + UINT32 ulCredentialAccessMode, /* in */ + UINT32 * pulCredentialSize, /* out */ + BYTE ** prgbCredentialData) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_GetCredential_TP(entry, ulCredentialType, + ulCredentialAccessMode, pulCredentialSize, + prgbCredentialData); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} +#endif + +TSS_RESULT RPC_SetOwnerInstall(TSS_HCONTEXT tspContext, /* in */ + TSS_BOOL state) /* in */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_SetOwnerInstall_TP(entry, state); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_TakeOwnership(TSS_HCONTEXT tspContext, /* in */ + UINT16 protocolID, /* in */ + UINT32 encOwnerAuthSize, /* in */ + BYTE * encOwnerAuth, /* in */ + UINT32 encSrkAuthSize, /* in */ + BYTE * encSrkAuth, /* in */ + UINT32 srkInfoSize, /* in */ + BYTE * srkInfo, /* in */ + TPM_AUTH * ownerAuth, /* in, out */ + UINT32 * srkKeySize, + BYTE ** srkKey) +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_TakeOwnership_TP(entry, protocolID, + encOwnerAuthSize, encOwnerAuth, + encSrkAuthSize, encSrkAuth, srkInfoSize, + srkInfo, ownerAuth, srkKeySize, srkKey); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_OIAP(TSS_HCONTEXT tspContext, /* in */ + TCS_AUTHHANDLE * authHandle, /* out */ + TCPA_NONCE * nonce0) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_OIAP_TP(entry, authHandle, nonce0); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_OSAP(TSS_HCONTEXT tspContext, /* in */ + TCPA_ENTITY_TYPE entityType, /* in */ + UINT32 entityValue, /* in */ + TPM_NONCE *nonceOddOSAP, /* in */ + TCS_AUTHHANDLE * authHandle, /* out */ + TCPA_NONCE * nonceEven, /* out */ + TCPA_NONCE * nonceEvenOSAP) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_OSAP_TP(entry, entityType, entityValue, nonceOddOSAP, + authHandle, nonceEven, nonceEvenOSAP); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_ChangeAuth(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE parentHandle, /* in */ + TCPA_PROTOCOL_ID protocolID, /* in */ + TCPA_ENCAUTH *newAuth, /* in */ + TCPA_ENTITY_TYPE entityType, /* in */ + UINT32 encDataSize, /* in */ + BYTE * encData, /* in */ + TPM_AUTH * ownerAuth, /* in, out */ + TPM_AUTH * entityAuth, /* in, out */ + UINT32 * outDataSize, /* out */ + BYTE ** outData) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_ChangeAuth_TP(entry, parentHandle, protocolID, newAuth, + entityType, encDataSize, encData, ownerAuth, + entityAuth, outDataSize, outData); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_ChangeAuthOwner(TSS_HCONTEXT tspContext, /* in */ + TCPA_PROTOCOL_ID protocolID, /* in */ + TCPA_ENCAUTH *newAuth, /* in */ + TCPA_ENTITY_TYPE entityType, /* in */ + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_ChangeAuthOwner_TP(entry, protocolID, newAuth, entityType, + ownerAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_ChangeAuthAsymStart(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE idHandle, /* in */ + TCPA_NONCE antiReplay, /* in */ + UINT32 KeySizeIn, /* in */ + BYTE * KeyDataIn, /* in */ + TPM_AUTH * pAuth, /* in, out */ + UINT32 * KeySizeOut, /* out */ + BYTE ** KeyDataOut, /* out */ + UINT32 * CertifyInfoSize, /* out */ + BYTE ** CertifyInfo, /* out */ + UINT32 * sigSize, /* out */ + BYTE ** sig, /* out */ + TCS_KEY_HANDLE * ephHandle) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_ChangeAuthAsymStart_TP(entry, idHandle, antiReplay, + KeySizeIn, KeyDataIn, pAuth, + KeySizeOut, KeyDataOut, + CertifyInfoSize, CertifyInfo, sigSize, + sig, ephHandle); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_ChangeAuthAsymFinish(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE parentHandle, /* in */ + TCS_KEY_HANDLE ephHandle, /* in */ + TCPA_ENTITY_TYPE entityType, /* in */ + TCPA_HMAC newAuthLink, /* in */ + UINT32 newAuthSize, /* in */ + BYTE * encNewAuth, /* in */ + UINT32 encDataSizeIn, /* in */ + BYTE * encDataIn, /* in */ + TPM_AUTH * ownerAuth, /* in, out */ + UINT32 * encDataSizeOut, /* out */ + BYTE ** encDataOut, /* out */ + TCPA_SALT_NONCE * saltNonce, /* out */ + TCPA_DIGEST * changeProof) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_ChangeAuthAsymFinish_TP(entry, parentHandle, ephHandle, + entityType, newAuthLink, + newAuthSize, encNewAuth, + encDataSizeIn, encDataIn, ownerAuth, + encDataSizeOut, encDataOut, saltNonce, + changeProof); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_TerminateHandle(TSS_HCONTEXT tspContext, /* in */ + TCS_AUTHHANDLE handle) /* in */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_TerminateHandle_TP(entry, handle); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_ActivateTPMIdentity(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE idKey, /* in */ + UINT32 blobSize, /* in */ + BYTE * blob, /* in */ + TPM_AUTH * idKeyAuth, /* in, out */ + TPM_AUTH * ownerAuth, /* in, out */ + UINT32 * SymmetricKeySize, /* out */ + BYTE ** SymmetricKey) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_ActivateTPMIdentity_TP(entry, idKey, blobSize, blob, idKeyAuth, + ownerAuth, SymmetricKeySize, + SymmetricKey); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_Extend(TSS_HCONTEXT tspContext, /* in */ + TCPA_PCRINDEX pcrNum, /* in */ + TCPA_DIGEST inDigest, /* in */ + TCPA_PCRVALUE * outDigest) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_Extend_TP(entry, pcrNum, inDigest, outDigest); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_PcrRead(TSS_HCONTEXT tspContext, /* in */ + TCPA_PCRINDEX pcrNum, /* in */ + TCPA_PCRVALUE * outDigest) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_PcrRead_TP(entry, pcrNum, outDigest); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_PcrReset(TSS_HCONTEXT tspContext, /* in */ + UINT32 pcrDataSizeIn, /* in */ + BYTE * pcrDataIn) /* in */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_PcrReset_TP(entry, pcrDataSizeIn, pcrDataIn); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + + +TSS_RESULT RPC_Quote(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + TCPA_NONCE *antiReplay, /* in */ + UINT32 pcrDataSizeIn, /* in */ + BYTE * pcrDataIn, /* in */ + TPM_AUTH * privAuth, /* in, out */ + UINT32 * pcrDataSizeOut, /* out */ + BYTE ** pcrDataOut, /* out */ + UINT32 * sigSize, /* out */ + BYTE ** sig) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_Quote_TP(entry, keyHandle, antiReplay, pcrDataSizeIn, + pcrDataIn, privAuth, pcrDataSizeOut, pcrDataOut, + sigSize, sig); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +#ifdef TSS_BUILD_TSS12 +TSS_RESULT RPC_Quote2(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + TCPA_NONCE *antiReplay, /* in */ + UINT32 pcrDataSizeIn, /* in */ + BYTE * pcrDataIn, /* in */ + TSS_BOOL addVersion, /* in */ + TPM_AUTH * privAuth, /* in,out */ + UINT32 * pcrDataSizeOut, /* out */ + BYTE ** pcrDataOut, /* out */ + UINT32 * versionInfoSize, /* out */ + BYTE ** versionInfo, /* out */ + UINT32 * sigSize, /* out */ + BYTE ** sig) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_Quote2_TP(entry, keyHandle, antiReplay, pcrDataSizeIn, pcrDataIn, + addVersion,privAuth, pcrDataSizeOut, pcrDataOut, + versionInfoSize, versionInfo,sigSize, sig); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} +#endif + +TSS_RESULT RPC_DirWriteAuth(TSS_HCONTEXT tspContext, /* in */ + TCPA_DIRINDEX dirIndex, /* in */ + TCPA_DIRVALUE *newContents, /* in */ + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_DirWriteAuth_TP(entry, dirIndex, newContents, ownerAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_DirRead(TSS_HCONTEXT tspContext, /* in */ + TCPA_DIRINDEX dirIndex, /* in */ + TCPA_DIRVALUE * dirValue) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_DirRead_TP(entry, dirIndex, dirValue); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_Seal(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + TCPA_ENCAUTH *encAuth, /* in */ + UINT32 pcrInfoSize, /* in */ + BYTE * PcrInfo, /* in */ + UINT32 inDataSize, /* in */ + BYTE * inData, /* in */ + TPM_AUTH * pubAuth, /* in, out */ + UINT32 * SealedDataSize, /* out */ + BYTE ** SealedData) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_Seal_TP(entry, keyHandle, encAuth, pcrInfoSize, PcrInfo, + inDataSize, inData, pubAuth, SealedDataSize, + SealedData); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +#ifdef TSS_BUILD_SEALX +TSS_RESULT RPC_Sealx(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + TCPA_ENCAUTH *encAuth, /* in */ + UINT32 pcrInfoSize, /* in */ + BYTE * PcrInfo, /* in */ + UINT32 inDataSize, /* in */ + BYTE * inData, /* in */ + TPM_AUTH * pubAuth, /* in, out */ + UINT32 * SealedDataSize, /* out */ + BYTE ** SealedData) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_Sealx_TP(entry, keyHandle, encAuth, pcrInfoSize, PcrInfo, + inDataSize, inData, pubAuth, SealedDataSize, + SealedData); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} +#endif + +TSS_RESULT RPC_Unseal(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE parentHandle, /* in */ + UINT32 SealedDataSize, /* in */ + BYTE * SealedData, /* in */ + TPM_AUTH * parentAuth, /* in, out */ + TPM_AUTH * dataAuth, /* in, out */ + UINT32 * DataSize, /* out */ + BYTE ** Data) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_Unseal_TP(entry, parentHandle, SealedDataSize, SealedData, + parentAuth, dataAuth, DataSize, Data); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_UnBind(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + UINT32 inDataSize, /* in */ + BYTE * inData, /* in */ + TPM_AUTH * privAuth, /* in, out */ + UINT32 * outDataSize, /* out */ + BYTE ** outData) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_UnBind_TP(entry, keyHandle, inDataSize, inData, privAuth, + outDataSize, outData); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_CreateMigrationBlob(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE parentHandle, /* in */ + TCPA_MIGRATE_SCHEME migrationType, /* in */ + UINT32 MigrationKeyAuthSize, /* in */ + BYTE * MigrationKeyAuth, /* in */ + UINT32 encDataSize, /* in */ + BYTE * encData, /* in */ + TPM_AUTH * parentAuth, /* in, out */ + TPM_AUTH * entityAuth, /* in, out */ + UINT32 * randomSize, /* out */ + BYTE ** random, /* out */ + UINT32 * outDataSize, /* out */ + BYTE ** outData) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_CreateMigrationBlob_TP(entry, parentHandle, + migrationType, MigrationKeyAuthSize, + MigrationKeyAuth, encDataSize, encData, + parentAuth, entityAuth, randomSize, + random, outDataSize, outData); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_ConvertMigrationBlob(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE parentHandle, /* in */ + UINT32 inDataSize, /* in */ + BYTE * inData, /* in */ + UINT32 randomSize, /* in */ + BYTE * random, /* in */ + TPM_AUTH * parentAuth, /* in, out */ + UINT32 * outDataSize, /* out */ + BYTE ** outData) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_ConvertMigrationBlob_TP(entry, parentHandle, + inDataSize, inData, randomSize, + random, parentAuth, outDataSize, + outData); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_AuthorizeMigrationKey(TSS_HCONTEXT tspContext, /* in */ + TCPA_MIGRATE_SCHEME migrateScheme, /* in */ + UINT32 MigrationKeySize, /* in */ + BYTE * MigrationKey, /* in */ + TPM_AUTH * ownerAuth, /* in, out */ + UINT32 * MigrationKeyAuthSize, /* out */ + BYTE ** MigrationKeyAuth) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_AuthorizeMigrationKey_TP(entry, migrateScheme, + MigrationKeySize, MigrationKey, + ownerAuth, MigrationKeyAuthSize, + MigrationKeyAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_CertifyKey(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE certHandle, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + TPM_NONCE * antiReplay, /* in */ + TPM_AUTH * certAuth, /* in, out */ + TPM_AUTH * keyAuth, /* in, out */ + UINT32 * CertifyInfoSize, /* out */ + BYTE ** CertifyInfo, /* out */ + UINT32 * outDataSize, /* out */ + BYTE ** outData) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_CertifyKey_TP(entry, certHandle, keyHandle, antiReplay, + certAuth, keyAuth, CertifyInfoSize, CertifyInfo, + outDataSize, outData); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_Sign(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + UINT32 areaToSignSize, /* in */ + BYTE * areaToSign, /* in */ + TPM_AUTH * privAuth, /* in, out */ + UINT32 * sigSize, /* out */ + BYTE ** sig) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_Sign_TP(entry, keyHandle, areaToSignSize, areaToSign, privAuth, + sigSize, sig); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_GetRandom(TSS_HCONTEXT tspContext, /* in */ + UINT32 bytesRequested, /* in */ + BYTE ** randomBytes) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_GetRandom_TP(entry, bytesRequested, randomBytes); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_StirRandom(TSS_HCONTEXT tspContext, /* in */ + UINT32 inDataSize, /* in */ + BYTE * inData) /* in */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_StirRandom_TP(entry, inDataSize, inData); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_GetTPMCapability(TSS_HCONTEXT tspContext, /* in */ + TCPA_CAPABILITY_AREA capArea, /* in */ + UINT32 subCapSize, /* in */ + BYTE * subCap, /* in */ + UINT32 * respSize, /* out */ + BYTE ** resp) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_GetTPMCapability_TP(entry, capArea, subCapSize, subCap, + respSize, resp); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_SetCapability(TSS_HCONTEXT tspContext, /* in */ + TCPA_CAPABILITY_AREA capArea, /* in */ + UINT32 subCapSize, /* in */ + BYTE * subCap, /* in */ + UINT32 valueSize, /* in */ + BYTE * value, /* in */ + TPM_AUTH *ownerAuth) /* in, out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_SetCapability_TP(entry, capArea, subCapSize, subCap, + valueSize, value, ownerAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_GetCapability(TSS_HCONTEXT tspContext, /* in */ + TCPA_CAPABILITY_AREA capArea, /* in */ + UINT32 subCapSize, /* in */ + BYTE * subCap, /* in */ + UINT32 * respSize, /* out */ + BYTE ** resp) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_GetCapability_TP(entry, capArea, subCapSize, subCap, respSize, + resp); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_GetCapabilitySigned(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + TCPA_NONCE antiReplay, /* in */ + TCPA_CAPABILITY_AREA capArea, /* in */ + UINT32 subCapSize, /* in */ + BYTE * subCap, /* in */ + TPM_AUTH * privAuth, /* in, out */ + TCPA_VERSION * Version, /* out */ + UINT32 * respSize, /* out */ + BYTE ** resp, /* out */ + UINT32 * sigSize, /* out */ + BYTE ** sig) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_GetCapabilitySigned_TP(entry, keyHandle, antiReplay, capArea, + subCapSize, subCap, privAuth, Version, + respSize, resp, sigSize, sig); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_GetCapabilityOwner(TSS_HCONTEXT tspContext, /* in */ + TPM_AUTH * pOwnerAuth, /* out */ + TCPA_VERSION * pVersion, /* out */ + UINT32 * pNonVolatileFlags, /* out */ + UINT32 * pVolatileFlags) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_GetCapabilityOwner_TP(entry, pOwnerAuth, pVersion, + pNonVolatileFlags, pVolatileFlags); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_CreateEndorsementKeyPair(TSS_HCONTEXT tspContext, /* in */ + TCPA_NONCE antiReplay, /* in */ + UINT32 endorsementKeyInfoSize, /* in */ + BYTE * endorsementKeyInfo, /* in */ + UINT32 * endorsementKeySize, /* out */ + BYTE ** endorsementKey, /* out */ + TCPA_DIGEST * checksum) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_CreateEndorsementKeyPair_TP(entry, antiReplay, + endorsementKeyInfoSize, + endorsementKeyInfo, + endorsementKeySize, + endorsementKey, checksum); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_ReadPubek(TSS_HCONTEXT tspContext, /* in */ + TCPA_NONCE antiReplay, /* in */ + UINT32 * pubEndorsementKeySize, /* out */ + BYTE ** pubEndorsementKey, /* out */ + TCPA_DIGEST * checksum) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_ReadPubek_TP(entry, antiReplay, pubEndorsementKeySize, + pubEndorsementKey, checksum); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_DisablePubekRead(TSS_HCONTEXT tspContext, /* in */ + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_DisablePubekRead_TP(entry, ownerAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_OwnerReadPubek(TSS_HCONTEXT tspContext, /* in */ + TPM_AUTH * ownerAuth, /* in, out */ + UINT32 * pubEndorsementKeySize, /* out */ + BYTE ** pubEndorsementKey) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_OwnerReadPubek_TP(entry, ownerAuth, pubEndorsementKeySize, + pubEndorsementKey); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +#ifdef TSS_BUILD_TSS12 +TSS_RESULT RPC_CreateRevocableEndorsementKeyPair(TSS_HCONTEXT tspContext, /* in */ + TPM_NONCE antiReplay, /* in */ + UINT32 endorsementKeyInfoSize,/* in */ + BYTE * endorsementKeyInfo, /* in */ + TSS_BOOL genResetAuth, /* in */ + TPM_DIGEST * eKResetAuth, /* in, out */ + UINT32 * endorsementKeySize, /* out */ + BYTE ** endorsementKey, /* out */ + TPM_DIGEST * checksum) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_CreateRevocableEndorsementKeyPair_TP(entry, antiReplay, + endorsementKeyInfoSize, + endorsementKeyInfo, + genResetAuth, + eKResetAuth, + endorsementKeySize, + endorsementKey, checksum); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_RevokeEndorsementKeyPair(TSS_HCONTEXT tspContext, /* in */ + TPM_DIGEST *EKResetAuth) /* in */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_RevokeEndorsementKeyPair_TP(entry, EKResetAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} +#endif + +TSS_RESULT RPC_SelfTestFull(TSS_HCONTEXT tspContext) /* in */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_SelfTestFull_TP(entry); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_CertifySelfTest(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + TCPA_NONCE antiReplay, /* in */ + TPM_AUTH * privAuth, /* in, out */ + UINT32 * sigSize, /* out */ + BYTE ** sig) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_CertifySelfTest_TP(entry, keyHandle, antiReplay, privAuth, + sigSize, sig); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_GetTestResult(TSS_HCONTEXT tspContext, /* in */ + UINT32 * outDataSize, /* out */ + BYTE ** outData) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_GetTestResult_TP(entry, outDataSize, outData); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_OwnerSetDisable(TSS_HCONTEXT tspContext, /* in */ + TSS_BOOL disableState, /* in */ + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_OwnerSetDisable_TP(entry, disableState, ownerAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +#ifdef TSS_BUILD_TSS12 +TSS_RESULT RPC_ResetLockValue(TSS_HCONTEXT tspContext, /* in */ + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_ResetLockValue_TP(entry, ownerAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} +#endif + +TSS_RESULT RPC_OwnerClear(TSS_HCONTEXT tspContext, /* in */ + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_OwnerClear_TP(entry, ownerAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_DisableOwnerClear(TSS_HCONTEXT tspContext, /* in */ + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_DisableOwnerClear_TP(entry, ownerAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_ForceClear(TSS_HCONTEXT tspContext) /* in */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_ForceClear_TP(entry); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_DisableForceClear(TSS_HCONTEXT tspContext) /* in */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_DisableForceClear_TP(entry); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_PhysicalDisable(TSS_HCONTEXT tspContext) /* in */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_PhysicalDisable_TP(entry); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_PhysicalEnable(TSS_HCONTEXT tspContext) /* in */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_PhysicalEnable_TP(entry); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_PhysicalSetDeactivated(TSS_HCONTEXT tspContext, /* in */ + TSS_BOOL state) /* in */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_PhysicalSetDeactivated_TP(entry, state); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_PhysicalPresence(TSS_HCONTEXT tspContext, /* in */ + TCPA_PHYSICAL_PRESENCE fPhysicalPresence) /* in */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_PhysicalPresence_TP(entry, fPhysicalPresence); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_SetTempDeactivated(TSS_HCONTEXT tspContext) /* in */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_SetTempDeactivated_TP(entry); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +#ifdef TSS_BUILD_TSS12 +TSS_RESULT RPC_SetTempDeactivated2(TSS_HCONTEXT tspContext, /* in */ + TPM_AUTH *operatorAuth) /* in, out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_SetTempDeactivated2_TP(entry, operatorAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} +#endif + +TSS_RESULT RPC_FieldUpgrade(TSS_HCONTEXT tspContext, /* in */ + UINT32 dataInSize, /* in */ + BYTE * dataIn, /* in */ + UINT32 * dataOutSize, /* out */ + BYTE ** dataOut, /* out */ + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = (UINT32) TSPERR(TSS_E_INTERNAL_ERROR); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_SetRedirection(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + UINT32 c1, /* in */ + UINT32 c2, /* in */ + TPM_AUTH * privAuth) /* in, out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = (UINT32) TSPERR(TSS_E_INTERNAL_ERROR); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_CreateMaintenanceArchive(TSS_HCONTEXT tspContext, /* in */ + TSS_BOOL generateRandom, /* in */ + TPM_AUTH * ownerAuth, /* in, out */ + UINT32 * randomSize, /* out */ + BYTE ** random, /* out */ + UINT32 * archiveSize, /* out */ + BYTE ** archive) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_CreateMaintenanceArchive_TP(entry, generateRandom, ownerAuth, + randomSize, random, archiveSize, + archive); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_LoadMaintenanceArchive(TSS_HCONTEXT tspContext, /* in */ + UINT32 dataInSize, /* in */ + BYTE * dataIn, /* in */ + TPM_AUTH * ownerAuth, /* in, out */ + UINT32 * dataOutSize, /* out */ + BYTE ** dataOut) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_LoadMaintenanceArchive_TP(entry, dataInSize, dataIn, ownerAuth, + dataOutSize, dataOut); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_KillMaintenanceFeature(TSS_HCONTEXT tspContext, /* in */ + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_KillMaintenanceFeature_TP(entry, ownerAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_LoadManuMaintPub(TSS_HCONTEXT tspContext, /* in */ + TCPA_NONCE antiReplay, /* in */ + UINT32 PubKeySize, /* in */ + BYTE * PubKey, /* in */ + TCPA_DIGEST * checksum) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_LoadManuMaintPub_TP(entry, antiReplay, PubKeySize, PubKey, + checksum); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT RPC_ReadManuMaintPub(TSS_HCONTEXT tspContext, /* in */ + TCPA_NONCE antiReplay, /* in */ + TCPA_DIGEST * checksum) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_ReadManuMaintPub_TP(entry, antiReplay, checksum); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +#ifdef TSS_BUILD_DAA +TSS_RESULT +RPC_DaaJoin(TSS_HCONTEXT tspContext, /* in */ + TPM_HANDLE daa_session, /* in */ + BYTE stage, /* in */ + UINT32 inputSize0, /* in */ + BYTE* inputData0, /* in */ + UINT32 inputSize1, /* in */ + BYTE* inputData1, /* in */ + TPM_AUTH* ownerAuth, /* in, out */ + UINT32* outputSize, /* out */ + BYTE** outputData) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_DaaJoin_TP(entry, daa_session, stage, inputSize0, inputData0, + inputSize1, inputData1, ownerAuth, outputSize, + outputData); + break; + default: + break; + } + + put_table_entry(entry); + + return result; + +} + +TSS_RESULT +RPC_DaaSign(TSS_HCONTEXT tspContext, /* in */ + TPM_HANDLE daa_session, /* in */ + BYTE stage, /* in */ + UINT32 inputSize0, /* in */ + BYTE* inputData0, /* in */ + UINT32 inputSize1, /* in */ + BYTE* inputData1, /* in */ + TPM_AUTH* ownerAuth, /* in, out */ + UINT32* outputSize, /* out */ + BYTE** outputData) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_DaaSign_TP(entry, daa_session, stage, inputSize0, inputData0, + inputSize1, inputData1, ownerAuth, outputSize, + outputData); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} +#endif + +#ifdef TSS_BUILD_COUNTER +TSS_RESULT +RPC_ReadCounter(TSS_HCONTEXT tspContext, /* in */ + TSS_COUNTER_ID idCounter, /* in */ + TPM_COUNTER_VALUE* counterValue) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_ReadCounter_TP(entry, idCounter, counterValue); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_CreateCounter(TSS_HCONTEXT tspContext, /* in */ + UINT32 LabelSize, /* in (=4) */ + BYTE* pLabel, /* in */ + TPM_ENCAUTH CounterAuth, /* in */ + TPM_AUTH* pOwnerAuth, /* in, out */ + TSS_COUNTER_ID* idCounter, /* out */ + TPM_COUNTER_VALUE* counterValue) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_CreateCounter_TP(entry, LabelSize, pLabel, CounterAuth, + pOwnerAuth, idCounter, counterValue); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_IncrementCounter(TSS_HCONTEXT tspContext, /* in */ + TSS_COUNTER_ID idCounter, /* in */ + TPM_AUTH* pCounterAuth, /* in, out */ + TPM_COUNTER_VALUE* counterValue) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_IncrementCounter_TP(entry, idCounter, pCounterAuth, + counterValue); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_ReleaseCounter(TSS_HCONTEXT tspContext, /* in */ + TSS_COUNTER_ID idCounter, /* in */ + TPM_AUTH* pCounterAuth) /* in, out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_ReleaseCounter_TP(entry, idCounter, pCounterAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_ReleaseCounterOwner(TSS_HCONTEXT tspContext, /* in */ + TSS_COUNTER_ID idCounter, /* in */ + TPM_AUTH* pOwnerAuth) /* in, out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_ReleaseCounterOwner_TP(entry, idCounter, pOwnerAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} +#endif + +#ifdef TSS_BUILD_TICK +TSS_RESULT +RPC_ReadCurrentTicks(TSS_HCONTEXT tspContext, /* in */ + UINT32* pulCurrentTime, /* out */ + BYTE** prgbCurrentTime) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_ReadCurrentTicks_TP(entry, pulCurrentTime, prgbCurrentTime); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_TickStampBlob(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE hKey, /* in */ + TPM_NONCE* antiReplay, /* in */ + TPM_DIGEST* digestToStamp, /* in */ + TPM_AUTH* privAuth, /* in, out */ + UINT32* pulSignatureLength, /* out */ + BYTE** prgbSignature, /* out */ + UINT32* pulTickCountLength, /* out */ + BYTE** prgbTickCount) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_TickStampBlob_TP(entry, hKey, antiReplay, digestToStamp, + privAuth, pulSignatureLength, + prgbSignature, pulTickCountLength, + prgbTickCount); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} +#endif + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +RPC_EstablishTransport(TSS_HCONTEXT tspContext, + UINT32 ulTransControlFlags, + TCS_KEY_HANDLE hEncKey, + UINT32 ulTransSessionInfoSize, + BYTE* rgbTransSessionInfo, + UINT32 ulSecretSize, + BYTE* rgbSecret, + TPM_AUTH* pEncKeyAuth, /* in, out */ + TPM_MODIFIER_INDICATOR* pbLocality, + TCS_HANDLE* hTransSession, + UINT32* ulCurrentTicksSize, + BYTE** prgbCurrentTicks, + TPM_NONCE* pTransNonce) +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_EstablishTransport_TP(entry, ulTransControlFlags, hEncKey, + ulTransSessionInfoSize, + rgbTransSessionInfo, ulSecretSize, + rgbSecret, pEncKeyAuth, pbLocality, + hTransSession, ulCurrentTicksSize, + prgbCurrentTicks, pTransNonce); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + + +TSS_RESULT +RPC_ExecuteTransport(TSS_HCONTEXT tspContext, + TPM_COMMAND_CODE unWrappedCommandOrdinal, + UINT32 ulWrappedCmdParamInSize, + BYTE* rgbWrappedCmdParamIn, + UINT32* pulHandleListSize, /* in, out */ + TCS_HANDLE** rghHandles, /* in, out */ + TPM_AUTH* pWrappedCmdAuth1, /* in, out */ + TPM_AUTH* pWrappedCmdAuth2, /* in, out */ + TPM_AUTH* pTransAuth, /* in, out */ + UINT64* punCurrentTicks, + TPM_MODIFIER_INDICATOR* pbLocality, + TPM_RESULT* pulWrappedCmdReturnCode, + UINT32* ulWrappedCmdParamOutSize, + BYTE** rgbWrappedCmdParamOut) +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_ExecuteTransport_TP(entry, unWrappedCommandOrdinal, + ulWrappedCmdParamInSize, + rgbWrappedCmdParamIn, pulHandleListSize, + rghHandles, pWrappedCmdAuth1, + pWrappedCmdAuth2, pTransAuth, + punCurrentTicks, pbLocality, + pulWrappedCmdReturnCode, + ulWrappedCmdParamOutSize, + rgbWrappedCmdParamOut); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_ReleaseTransportSigned(TSS_HCONTEXT tspContext, + TCS_KEY_HANDLE hSignatureKey, + TPM_NONCE* AntiReplayNonce, + TPM_AUTH* pKeyAuth, /* in, out */ + TPM_AUTH* pTransAuth, /* in, out */ + TPM_MODIFIER_INDICATOR* pbLocality, + UINT32* pulCurrentTicksSize, + BYTE** prgbCurrentTicks, + UINT32* pulSignatureSize, + BYTE** prgbSignature) +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(tspContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_ReleaseTransportSigned_TP(entry, hSignatureKey, + AntiReplayNonce, pKeyAuth, + pTransAuth, pbLocality, + pulCurrentTicksSize, + prgbCurrentTicks, pulSignatureSize, + prgbSignature); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} +#endif + +#ifdef TSS_BUILD_NV +TSS_RESULT +RPC_NV_DefineOrReleaseSpace(TSS_HCONTEXT hContext, /* in */ + UINT32 cPubInfoSize, /* in */ + BYTE* pPubInfo, /* in */ + TCPA_ENCAUTH encAuth, /* in */ + TPM_AUTH* pAuth) /* in, out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_NV_DefineOrReleaseSpace_TP(entry, cPubInfoSize, pPubInfo, + encAuth, pAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_NV_WriteValue(TSS_HCONTEXT hContext, /* in */ + TSS_NV_INDEX hNVStore, /* in */ + UINT32 offset, /* in */ + UINT32 ulDataLength, /* in */ + BYTE* rgbDataToWrite, /* in */ + TPM_AUTH* privAuth) /* in, out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_NV_WriteValue_TP(entry, hNVStore, offset, ulDataLength, + rgbDataToWrite, privAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + + +TSS_RESULT +RPC_NV_WriteValueAuth(TSS_HCONTEXT hContext, /* in */ + TSS_NV_INDEX hNVStore, /* in */ + UINT32 offset, /* in */ + UINT32 ulDataLength, /* in */ + BYTE* rgbDataToWrite, /* in */ + TPM_AUTH* NVAuth) /* in, out */ +{ + + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_NV_WriteValueAuth_TP(entry, hNVStore, offset, ulDataLength, + rgbDataToWrite, NVAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + + +TSS_RESULT +RPC_NV_ReadValue(TSS_HCONTEXT hContext, /* in */ + TSS_NV_INDEX hNVStore, /* in */ + UINT32 offset, /* in */ + UINT32* pulDataLength, /* in, out */ + TPM_AUTH* privAuth, /* in, out */ + BYTE** rgbDataRead) /* out */ +{ + + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_NV_ReadValue_TP(entry, hNVStore, offset, pulDataLength, + privAuth, rgbDataRead); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_NV_ReadValueAuth(TSS_HCONTEXT hContext, /* in */ + TSS_NV_INDEX hNVStore, /* in */ + UINT32 offset, /* in */ + UINT32* pulDataLength, /* in, out */ + TPM_AUTH* NVAuth, /* in, out */ + BYTE** rgbDataRead) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_NV_ReadValueAuth_TP(entry, hNVStore, offset, pulDataLength, + NVAuth, rgbDataRead); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} +#endif + +#ifdef TSS_BUILD_AUDIT +TSS_RESULT +RPC_SetOrdinalAuditStatus(TSS_HCONTEXT hContext, /* in */ + TPM_AUTH *ownerAuth, /* in/out */ + UINT32 ulOrdinal, /* in */ + TSS_BOOL bAuditState) /* in */ +{ + TSS_RESULT result = TSS_SUCCESS; + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_SetOrdinalAuditStatus_TP(entry, ownerAuth, ulOrdinal, + bAuditState); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_GetAuditDigest(TSS_HCONTEXT hContext, /* in */ + UINT32 startOrdinal, /* in */ + TPM_DIGEST *auditDigest, /* out */ + UINT32 *counterValueSize, /* out */ + BYTE **counterValue, /* out */ + TSS_BOOL *more, /* out */ + UINT32 *ordSize, /* out */ + UINT32 **ordList) /* out */ +{ + TSS_RESULT result = TSS_SUCCESS; + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_GetAuditDigest_TP(entry, startOrdinal, auditDigest, + counterValueSize, counterValue, more, + ordSize, ordList); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_GetAuditDigestSigned(TSS_HCONTEXT hContext, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + TSS_BOOL closeAudit, /* in */ + TPM_NONCE *antiReplay, /* in */ + TPM_AUTH *privAuth, /* in/out */ + UINT32 *counterValueSize, /* out */ + BYTE **counterValue, /* out */ + TPM_DIGEST *auditDigest, /* out */ + TPM_DIGEST *ordinalDigest, /* out */ + UINT32 *sigSize, /* out */ + BYTE **sig) /* out */ +{ + TSS_RESULT result = TSS_SUCCESS; + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_GetAuditDigestSigned_TP(entry, keyHandle, closeAudit, + antiReplay, privAuth, + counterValueSize, counterValue, + auditDigest, ordinalDigest, + sigSize, sig); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} +#endif + +#ifdef TSS_BUILD_TSS12 +TSS_RESULT +RPC_SetOperatorAuth(TSS_HCONTEXT hContext, /* in */ + TCPA_SECRET *operatorAuth) /* in */ +{ + TSS_RESULT result = TSS_SUCCESS; + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_SetOperatorAuth_TP(entry, operatorAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_OwnerReadInternalPub(TSS_HCONTEXT hContext, /* in */ + TCS_KEY_HANDLE hKey, /* in */ + TPM_AUTH* pOwnerAuth, /* in, out */ + UINT32* punPubKeySize, /* out */ + BYTE** ppbPubKeyData) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_OwnerReadInternalPub_TP(entry, hKey, pOwnerAuth, punPubKeySize, + ppbPubKeyData); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} +#endif + +#ifdef TSS_BUILD_DELEGATION +TSS_RESULT +RPC_Delegate_Manage(TSS_HCONTEXT hContext, /* in */ + TPM_FAMILY_ID familyID, /* in */ + TPM_FAMILY_OPERATION opFlag, /* in */ + UINT32 opDataSize, /* in */ + BYTE *opData, /* in */ + TPM_AUTH *ownerAuth, /* in, out */ + UINT32 *retDataSize, /* out */ + BYTE **retData) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_Delegate_Manage_TP(entry, familyID, opFlag, opDataSize, opData, + ownerAuth, retDataSize, retData); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_Delegate_CreateKeyDelegation(TSS_HCONTEXT hContext, /* in */ + TCS_KEY_HANDLE hKey, /* in */ + UINT32 publicInfoSize, /* in */ + BYTE *publicInfo, /* in */ + TPM_ENCAUTH *encDelAuth, /* in */ + TPM_AUTH *keyAuth, /* in, out */ + UINT32 *blobSize, /* out */ + BYTE **blob) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_Delegate_CreateKeyDelegation_TP(entry, hKey, publicInfoSize, + publicInfo, encDelAuth, + keyAuth, blobSize, blob); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_Delegate_CreateOwnerDelegation(TSS_HCONTEXT hContext, /* in */ + TSS_BOOL increment, /* in */ + UINT32 publicInfoSize, /* in */ + BYTE *publicInfo, /* in */ + TPM_ENCAUTH *encDelAuth, /* in */ + TPM_AUTH *ownerAuth, /* in, out */ + UINT32 *blobSize, /* out */ + BYTE **blob) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_Delegate_CreateOwnerDelegation_TP(entry, increment, + publicInfoSize, publicInfo, + encDelAuth, ownerAuth, + blobSize, blob); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_Delegate_LoadOwnerDelegation(TSS_HCONTEXT hContext, /* in */ + TPM_DELEGATE_INDEX index, /* in */ + UINT32 blobSize, /* in */ + BYTE *blob, /* in */ + TPM_AUTH *ownerAuth) /* in, out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_Delegate_LoadOwnerDelegation_TP(entry, index, blobSize, blob, + ownerAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_Delegate_ReadTable(TSS_HCONTEXT hContext, /* in */ + UINT32 *familyTableSize, /* out */ + BYTE **familyTable, /* out */ + UINT32 *delegateTableSize, /* out */ + BYTE **delegateTable) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_Delegate_ReadTable_TP(entry, familyTableSize, familyTable, + delegateTableSize, delegateTable); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_Delegate_UpdateVerificationCount(TSS_HCONTEXT hContext, /* in */ + UINT32 inputSize, /* in */ + BYTE *input, /* in */ + TPM_AUTH *ownerAuth, /* in, out */ + UINT32 *outputSize, /* out */ + BYTE **output) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_Delegate_UpdateVerificationCount_TP(entry, inputSize, input, + ownerAuth, outputSize, + output); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_Delegate_VerifyDelegation(TSS_HCONTEXT hContext, /* in */ + UINT32 delegateSize, /* in */ + BYTE *delegate) /* in */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_Delegate_VerifyDelegation_TP(entry, delegateSize, delegate); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_DSAP(TSS_HCONTEXT hContext, /* in */ + TPM_ENTITY_TYPE entityType, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + TPM_NONCE *nonceOddDSAP, /* in */ + UINT32 entityValueSize, /* in */ + BYTE * entityValue, /* in */ + TCS_AUTHHANDLE *authHandle, /* out */ + TPM_NONCE *nonceEven, /* out */ + TPM_NONCE *nonceEvenDSAP) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_DSAP_TP(entry, entityType, keyHandle, nonceOddDSAP, + entityValueSize, entityValue, authHandle, nonceEven, + nonceEvenDSAP); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +#endif + +#ifdef TSS_BUILD_CMK +TSS_RESULT +RPC_CMK_SetRestrictions(TSS_HCONTEXT hContext, /* in */ + TSS_CMK_DELEGATE restriction, /* in */ + TPM_AUTH *ownerAuth) /* in, out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_CMK_SetRestrictions_TP(entry, restriction, ownerAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_CMK_ApproveMA(TSS_HCONTEXT hContext, /* in */ + TPM_DIGEST migAuthorityDigest, /* in */ + TPM_AUTH *ownerAuth, /* in, out */ + TPM_HMAC *migAuthorityApproval) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_CMK_ApproveMA_TP(entry, migAuthorityDigest, ownerAuth, + migAuthorityApproval); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_CMK_CreateKey(TSS_HCONTEXT hContext, /* in */ + TCS_KEY_HANDLE hWrappingKey, /* in */ + TPM_ENCAUTH *keyUsageAuth, /* in */ + TPM_HMAC *migAuthorityApproval, /* in */ + TPM_DIGEST *migAuthorityDigest, /* in */ + UINT32 *keyDataSize, /* in, out */ + BYTE **keyData, /* in, out */ + TPM_AUTH *pAuth) /* in, out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_CMK_CreateKey_TP(entry, hWrappingKey, keyUsageAuth, + migAuthorityApproval, migAuthorityDigest, keyDataSize, + keyData, pAuth); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_CMK_CreateTicket(TSS_HCONTEXT hContext, /* in */ + UINT32 publicVerifyKeySize, /* in */ + BYTE *publicVerifyKey, /* in */ + TPM_DIGEST signedData, /* in */ + UINT32 sigValueSize, /* in */ + BYTE *sigValue, /* in */ + TPM_AUTH *ownerAuth, /* in, out */ + TPM_HMAC *sigTicket) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_CMK_CreateTicket_TP(entry, publicVerifyKeySize, + publicVerifyKey, signedData, sigValueSize, sigValue, + ownerAuth, sigTicket); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_CMK_CreateBlob(TSS_HCONTEXT hContext, /* in */ + TCS_KEY_HANDLE hParentKey, /* in */ + TSS_MIGRATE_SCHEME migrationType, /* in */ + UINT32 migKeyAuthSize, /* in */ + BYTE *migKeyAuth, /* in */ + TPM_DIGEST pubSourceKeyDigest, /* in */ + UINT32 msaListSize, /* in */ + BYTE *msaList, /* in */ + UINT32 restrictTicketSize, /* in */ + BYTE *restrictTicket, /* in */ + UINT32 sigTicketSize, /* in */ + BYTE *sigTicket, /* in */ + UINT32 encDataSize, /* in */ + BYTE *encData, /* in */ + TPM_AUTH *pAuth, /* in, out */ + UINT32 *randomSize, /* out */ + BYTE **random, /* out */ + UINT32 *outDataSize, /* out */ + BYTE **outData) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_CMK_CreateBlob_TP(entry, hParentKey, migrationType, + migKeyAuthSize, migKeyAuth, pubSourceKeyDigest, + msaListSize, msaList, restrictTicketSize, restrictTicket, + sigTicketSize, sigTicket, encDataSize, encData, pAuth, + randomSize, random, outDataSize, outData); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_CMK_ConvertMigration(TSS_HCONTEXT hContext, /* in */ + TCS_KEY_HANDLE hParentHandle, /* in */ + TPM_CMK_AUTH restrictTicket, /* in */ + TPM_HMAC sigTicket, /* in */ + UINT32 keyDataSize, /* in */ + BYTE *keyData, /* in */ + UINT32 msaListSize, /* in */ + BYTE *msaList, /* in */ + UINT32 randomSize, /* in */ + BYTE *random, /* in */ + TPM_AUTH *pAuth, /* in, out */ + UINT32 *outDataSize, /* out */ + BYTE **outData) /* out */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_CMK_ConvertMigration_TP(entry, hParentHandle, restrictTicket, + sigTicket, keyDataSize, keyData, msaListSize, msaList, + randomSize, random, pAuth, outDataSize, outData); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} +#endif + +#ifdef TSS_BUILD_TSS12 +TSS_RESULT +RPC_FlushSpecific(TSS_HCONTEXT hContext, /* in */ + TCS_HANDLE hResHandle, /* in */ + TPM_RESOURCE_TYPE resourceType) /* in */ +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_FlushSpecific_TP(entry, hResHandle, resourceType); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} + +TSS_RESULT +RPC_KeyControlOwner(TCS_CONTEXT_HANDLE hContext, /* in */ + TCS_KEY_HANDLE hKey, /* in */ + UINT32 ulPublicInfoLength, /* in */ + BYTE* rgbPublicInfo, /* in */ + UINT32 attribName, /* in */ + TSS_BOOL attribValue, /* in */ + TPM_AUTH* pOwnerAuth, /* in, out */ + TSS_UUID* pUuidData) /* out */ + +{ + TSS_RESULT result = (TSS_E_INTERNAL_ERROR | TSS_LAYER_TSP); + struct host_table_entry *entry = get_table_entry(hContext); + + if (entry == NULL) + return TSPERR(TSS_E_NO_CONNECTION); + + switch (entry->type) { + case CONNECTION_TYPE_TCP_PERSISTANT: + result = RPC_KeyControlOwner_TP(entry, hKey, + ulPublicInfoLength, + rgbPublicInfo, + attribName, + attribValue, + pOwnerAuth, + pUuidData); + break; + default: + break; + } + + put_table_entry(entry); + + return result; +} +#endif + diff --git a/src/tspi/rpc/tcstp/rpc.c b/src/tspi/rpc/tcstp/rpc.c new file mode 100644 index 0000000..da710f8 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc.c @@ -0,0 +1,514 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <unistd.h> +#include <errno.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> +#include <limits.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +void +initData(struct tcsd_comm_data *comm, int parm_count) +{ + /* min packet size should be the size of the header */ + memset(&comm->hdr, 0, sizeof(struct tcsd_packet_hdr)); + comm->hdr.packet_size = sizeof(struct tcsd_packet_hdr); + if (parm_count > 0) { + comm->hdr.type_offset = sizeof(struct tcsd_packet_hdr); + comm->hdr.parm_offset = comm->hdr.type_offset + + (sizeof(TCSD_PACKET_TYPE) * parm_count); + comm->hdr.packet_size = comm->hdr.parm_offset; + } + + memset(comm->buf, 0, comm->buf_size); +} + +int +loadData(UINT64 *offset, TCSD_PACKET_TYPE data_type, void *data, int data_size, BYTE *blob) +{ + switch (data_type) { + case TCSD_PACKET_TYPE_BYTE: + Trspi_LoadBlob_BYTE(offset, *((BYTE *) (data)), blob); + break; + case TCSD_PACKET_TYPE_BOOL: + Trspi_LoadBlob_BOOL(offset, *((TSS_BOOL *) (data)), blob); + break; + case TCSD_PACKET_TYPE_UINT16: + Trspi_LoadBlob_UINT16(offset, *((UINT16 *) (data)), blob); + break; + case TCSD_PACKET_TYPE_UINT32: + Trspi_LoadBlob_UINT32(offset, *((UINT32 *) (data)), blob); + break; + case TCSD_PACKET_TYPE_PBYTE: + Trspi_LoadBlob(offset, data_size, blob, (BYTE *)data); + break; + case TCSD_PACKET_TYPE_NONCE: + Trspi_LoadBlob(offset, 20, blob, ((TCPA_NONCE *)data)->nonce); + break; + case TCSD_PACKET_TYPE_DIGEST: + Trspi_LoadBlob(offset, 20, blob, ((TCPA_DIGEST *)data)->digest); + break; + case TCSD_PACKET_TYPE_AUTH: + LoadBlob_AUTH(offset, blob, ((TPM_AUTH *)data)); + break; + case TCSD_PACKET_TYPE_UUID: + Trspi_LoadBlob_UUID(offset, blob, *((TSS_UUID *)data)); + break; + case TCSD_PACKET_TYPE_ENCAUTH: + Trspi_LoadBlob(offset, 20, blob, ((TCPA_ENCAUTH *)data)->authdata); + break; + case TCSD_PACKET_TYPE_VERSION: + Trspi_LoadBlob_TCPA_VERSION(offset, blob, *((TCPA_VERSION *)data)); + break; +#ifdef TSS_BUILD_PS + case TCSD_PACKET_TYPE_LOADKEY_INFO: + LoadBlob_LOADKEY_INFO(offset, blob, ((TCS_LOADKEY_INFO *)data)); + break; +#endif + case TCSD_PACKET_TYPE_PCR_EVENT: + Trspi_LoadBlob_PCR_EVENT(offset, blob, ((TSS_PCR_EVENT *)data)); + break; + case TCSD_PACKET_TYPE_COUNTER_VALUE: + Trspi_LoadBlob_COUNTER_VALUE(offset, blob, ((TPM_COUNTER_VALUE *)data)); + break; + case TCSD_PACKET_TYPE_SECRET: + Trspi_LoadBlob(offset, 20, blob, ((TCPA_SECRET *)data)->authdata); + break; + default: + LogError("TCSD packet type unknown! (0x%x)", data_type & 0xff); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + return TSS_SUCCESS; +} + +int +setData(TCSD_PACKET_TYPE dataType, + int index, + void *theData, + int theDataSize, + struct tcsd_comm_data *comm) +{ + UINT64 old_offset, offset; + TSS_RESULT result; + TCSD_PACKET_TYPE *type; + + /* Calculate the size of the area needed (use NULL for blob address) */ + offset = 0; + if ((result = loadData(&offset, dataType, theData, theDataSize, NULL))) + return result; + if ((comm->hdr.packet_size + offset) > TSS_TPM_TXBLOB_SIZE) { + LogError("Too much data to be transmitted!"); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if ((comm->hdr.packet_size + offset) > comm->buf_size) { + /* reallocate the buffer */ + BYTE *buffer; + int buffer_size = comm->hdr.packet_size + offset; + + LogDebug("Increasing communication buffer to %d bytes.", buffer_size); + buffer = realloc(comm->buf, buffer_size); + if (buffer == NULL) { + LogError("realloc of %d bytes failed.", buffer_size); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + comm->buf_size = buffer_size; + comm->buf = buffer; + } + + offset = old_offset = comm->hdr.parm_offset + comm->hdr.parm_size; + if ((result = loadData(&offset, dataType, theData, theDataSize, comm->buf))) + return result; + type = (TCSD_PACKET_TYPE *)(comm->buf + comm->hdr.type_offset) + index; + *type = dataType; + comm->hdr.type_size += sizeof(TCSD_PACKET_TYPE); + comm->hdr.parm_size += (offset - old_offset); + + comm->hdr.packet_size = offset; + comm->hdr.num_parms++; + + return TSS_SUCCESS; +} + +UINT32 +getData(TCSD_PACKET_TYPE dataType, + int index, + void *theData, + int theDataSize, + struct tcsd_comm_data *comm) +{ + TSS_RESULT result; + UINT64 old_offset, offset; + TCSD_PACKET_TYPE *type = (TCSD_PACKET_TYPE *)(comm->buf + comm->hdr.type_offset) + index; + + if ((UINT32)index >= comm->hdr.num_parms || dataType != *type) { + LogDebug("Data type of TCS packet element %d doesn't match.", index); + return TSS_TCP_RPC_BAD_PACKET_TYPE; + } + old_offset = offset = comm->hdr.parm_offset; + switch (dataType) { + case TCSD_PACKET_TYPE_BYTE: + Trspi_UnloadBlob_BYTE(&offset, (BYTE *)theData, comm->buf); + break; + case TCSD_PACKET_TYPE_BOOL: + Trspi_UnloadBlob_BOOL(&offset, (TSS_BOOL *)theData, comm->buf); + break; + case TCSD_PACKET_TYPE_UINT16: + Trspi_UnloadBlob_UINT16(&offset, (UINT16 *)theData, comm->buf); + break; + case TCSD_PACKET_TYPE_UINT32: + Trspi_UnloadBlob_UINT32(&offset, (UINT32 *)theData, comm->buf); + break; + case TCSD_PACKET_TYPE_UINT64: + Trspi_UnloadBlob_UINT64(&offset, (UINT64 *)theData, comm->buf); + break; + case TCSD_PACKET_TYPE_PBYTE: + Trspi_UnloadBlob(&offset, theDataSize, comm->buf, (BYTE *)theData); + break; + case TCSD_PACKET_TYPE_NONCE: + Trspi_UnloadBlob_NONCE(&offset, comm->buf, (TPM_NONCE *)theData); + break; + case TCSD_PACKET_TYPE_DIGEST: + Trspi_UnloadBlob(&offset, sizeof(TCPA_DIGEST), comm->buf, + ((TCPA_DIGEST *)theData)->digest); + break; + case TCSD_PACKET_TYPE_AUTH: + UnloadBlob_AUTH(&offset, comm->buf, ((TPM_AUTH *)theData)); + break; + case TCSD_PACKET_TYPE_UUID: + Trspi_UnloadBlob_UUID(&offset, comm->buf, ((TSS_UUID *)theData)); + break; + case TCSD_PACKET_TYPE_ENCAUTH: + Trspi_UnloadBlob(&offset, sizeof(TCPA_ENCAUTH), comm->buf, + ((TCPA_ENCAUTH *)theData)->authdata); + break; + case TCSD_PACKET_TYPE_VERSION: + Trspi_UnloadBlob_TCPA_VERSION(&offset, comm->buf, + ((TCPA_VERSION *)theData)); + break; + case TCSD_PACKET_TYPE_KM_KEYINFO: + if ((result = Trspi_UnloadBlob_KM_KEYINFO(&offset, comm->buf, + ((TSS_KM_KEYINFO *)theData)))) + return result; + break; + case TCSD_PACKET_TYPE_KM_KEYINFO2: + if ((result = Trspi_UnloadBlob_KM_KEYINFO2(&offset, comm->buf, + ((TSS_KM_KEYINFO2 *)theData)))) + return result; + break; +#ifdef TSS_BUILD_PS + case TCSD_PACKET_TYPE_LOADKEY_INFO: + UnloadBlob_LOADKEY_INFO(&offset, comm->buf, ((TCS_LOADKEY_INFO *)theData)); + break; +#endif + case TCSD_PACKET_TYPE_PCR_EVENT: + if ((result = Trspi_UnloadBlob_PCR_EVENT(&offset, comm->buf, + ((TSS_PCR_EVENT *)theData)))) + return result; + break; + case TCSD_PACKET_TYPE_COUNTER_VALUE: + Trspi_UnloadBlob_COUNTER_VALUE(&offset, comm->buf, + ((TPM_COUNTER_VALUE *)theData)); + break; + case TCSD_PACKET_TYPE_SECRET: + Trspi_UnloadBlob(&offset, sizeof(TCPA_SECRET), comm->buf, + ((TCPA_SECRET *)theData)->authdata); + break; + default: + LogError("unknown data type (%d) in TCSD packet!", dataType); + return -1; + } + comm->hdr.parm_offset = offset; + comm->hdr.parm_size -= (offset - old_offset); + + return TSS_SUCCESS; +} + +TSS_RESULT +sendTCSDPacket(struct host_table_entry *hte) +{ + TSS_RESULT rc; + UINT64 offset = 0; + + Trspi_LoadBlob_UINT32(&offset, hte->comm.hdr.packet_size, hte->comm.buf); + Trspi_LoadBlob_UINT32(&offset, hte->comm.hdr.u.ordinal, hte->comm.buf); + Trspi_LoadBlob_UINT32(&offset, hte->comm.hdr.num_parms, hte->comm.buf); + Trspi_LoadBlob_UINT32(&offset, hte->comm.hdr.type_size, hte->comm.buf); + Trspi_LoadBlob_UINT32(&offset, hte->comm.hdr.type_offset, hte->comm.buf); + Trspi_LoadBlob_UINT32(&offset, hte->comm.hdr.parm_size, hte->comm.buf); + Trspi_LoadBlob_UINT32(&offset, hte->comm.hdr.parm_offset, hte->comm.buf); + +#if 0 + /* --- Send it */ + printBuffer(hte->comm.buf, hte->comm.hdr.packet_size); + LogInfo("Sending Packet with TCSD ordinal 0x%X", hte->comm.hdr.u.ordinal); +#endif + /* if the ordinal is open context, there are some host table entry + * manipulations that must be done, so call _init + */ + if (hte->comm.hdr.u.ordinal == TCSD_ORD_OPENCONTEXT) { + if ((rc = send_init(hte))) { + LogError("Failed to send packet"); + return rc; + } + } else { + if ((rc = tcs_sendit(hte))) { + LogError("Failed to send packet"); + return rc; + } + } + + /* create a platform version of the tcsd header */ + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, &hte->comm.hdr.packet_size, hte->comm.buf); + Trspi_UnloadBlob_UINT32(&offset, &hte->comm.hdr.u.result, hte->comm.buf); + Trspi_UnloadBlob_UINT32(&offset, &hte->comm.hdr.num_parms, hte->comm.buf); + Trspi_UnloadBlob_UINT32(&offset, &hte->comm.hdr.type_size, hte->comm.buf); + Trspi_UnloadBlob_UINT32(&offset, &hte->comm.hdr.type_offset, hte->comm.buf); + Trspi_UnloadBlob_UINT32(&offset, &hte->comm.hdr.parm_size, hte->comm.buf); + Trspi_UnloadBlob_UINT32(&offset, &hte->comm.hdr.parm_offset, hte->comm.buf); + + return TSS_SUCCESS; +} + +int +recv_from_socket(int sock, void *buffer, int size) +{ + int recv_size = 0, recv_total = 0; + + while (recv_total < size) { + errno = 0; + if ((recv_size = recv(sock, buffer+recv_total, size-recv_total, 0)) <= 0) { + if (recv_size < 0) { + if (errno == EINTR) + continue; + LogError("Socket receive connection error: %s.", strerror(errno)); + } else { + LogDebug("Socket connection closed."); + } + + return -1; + } + recv_total += recv_size; + } + + return recv_total; +} + +int +send_to_socket(int sock, void *buffer, int size) +{ + int send_size = 0, send_total = 0; + + while (send_total < size) { + if ((send_size = send(sock, buffer+send_total, size-send_total, 0)) < 0) { + LogError("Socket send connection error: %s.", strerror(errno)); + return -1; + } + send_total += send_size; + } + + return send_total; +} + +TSS_RESULT +send_init(struct host_table_entry *hte) +{ + int sd; + int recv_size; + BYTE *buffer; + TSS_RESULT result; + + struct sockaddr_in addr; + struct hostent *hEnt = NULL; + + sd = socket(PF_INET, SOCK_STREAM, 0); + if (sd == -1) { + LogError("socket: %s", strerror(errno)); + result = TSPERR(TSS_E_COMM_FAILURE); + goto err_exit; + } + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(get_port()); + + LogDebug("Sending TSP packet to host %s.", hte->hostname); + + /* try to resolve by hostname first */ + hEnt = gethostbyname((char *)hte->hostname); + if (hEnt == NULL) { + /* if by hostname fails, try by dot notation */ + if (inet_aton((char *)hte->hostname, &addr.sin_addr) == 0) { + LogError("hostname %s does not resolve to a valid address.", hte->hostname); + result = TSPERR(TSS_E_CONNECTION_FAILED); + goto err_exit; + } + } else { + memcpy(&addr.sin_addr, hEnt->h_addr_list[0], 4); + } + + LogDebug("Connecting to %s", inet_ntoa(addr.sin_addr)); + + if (connect(sd, (struct sockaddr *) &addr, sizeof (addr))) { + LogError("connect: %s", strerror(errno)); + result = TSPERR(TSS_E_COMM_FAILURE); + goto err_exit; + } + + if (send_to_socket(sd, hte->comm.buf, hte->comm.hdr.packet_size) < 0) { + result = TSPERR(TSS_E_COMM_FAILURE); + goto err_exit; + } + + buffer = hte->comm.buf; + recv_size = sizeof(struct tcsd_packet_hdr); + if (recv_from_socket(sd, buffer, recv_size) < 0) { + result = TSPERR(TSS_E_COMM_FAILURE); + goto err_exit; + } + buffer += sizeof(struct tcsd_packet_hdr); /* increment the receive buffer pointer */ + + /* check the packet size */ + recv_size = Decode_UINT32(hte->comm.buf); + if (recv_size < (int)sizeof(struct tcsd_packet_hdr)) { + LogError("Packet to receive from socket %d is too small (%d bytes)", + sd, recv_size); + result = TSPERR(TSS_E_COMM_FAILURE); + goto err_exit; + } + + if (recv_size > (int) hte->comm.buf_size ) { + BYTE *new_buffer; + + LogDebug("Increasing communication buffer to %d bytes.", recv_size); + new_buffer = realloc(hte->comm.buf, recv_size); + if (new_buffer == NULL) { + LogError("realloc of %d bytes failed.", recv_size); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto err_exit; + } + buffer = new_buffer + sizeof(struct tcsd_packet_hdr); + hte->comm.buf_size = recv_size; + hte->comm.buf = new_buffer; + } + + /* get the rest of the packet */ + recv_size -= sizeof(struct tcsd_packet_hdr); /* already received the header */ + if (recv_from_socket(sd, buffer, recv_size) < 0) { + result = TSPERR(TSS_E_COMM_FAILURE); + goto err_exit; + } + + hte->socket = sd; + + return TSS_SUCCESS; + +err_exit: + close(sd); + return result; +} + +TSS_RESULT +tcs_sendit(struct host_table_entry *hte) +{ + int recv_size; + BYTE *buffer; + TSS_RESULT result; + + if (send_to_socket(hte->socket, hte->comm.buf, hte->comm.hdr.packet_size) < 0) { + result = TSPERR(TSS_E_COMM_FAILURE); + goto err_exit; + } + + buffer = hte->comm.buf; + recv_size = sizeof(struct tcsd_packet_hdr); + if ((recv_size = recv_from_socket(hte->socket, buffer, recv_size)) < 0) { + result = TSPERR(TSS_E_COMM_FAILURE); + goto err_exit; + } + buffer += recv_size; /* increment the receive buffer pointer */ + + /* check the packet size */ + recv_size = Decode_UINT32(hte->comm.buf); + if (recv_size < (int)sizeof(struct tcsd_packet_hdr)) { + LogError("Packet to receive from socket %d is too small (%d bytes)", + hte->socket, recv_size); + result = TSPERR(TSS_E_COMM_FAILURE); + goto err_exit; + } + + if (recv_size > (int) hte->comm.buf_size ) { + BYTE *new_buffer; + + LogDebug("Increasing communication buffer to %d bytes.", recv_size); + new_buffer = realloc(hte->comm.buf, recv_size); + if (new_buffer == NULL) { + LogError("realloc of %d bytes failed.", recv_size); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto err_exit; + } + buffer = new_buffer + sizeof(struct tcsd_packet_hdr); + hte->comm.buf_size = recv_size; + hte->comm.buf = new_buffer; + } + + /* get the rest of the packet */ + recv_size -= sizeof(struct tcsd_packet_hdr); /* already received the header */ + if ((recv_size = recv_from_socket(hte->socket, buffer, recv_size)) < 0) { + result = TSPERR(TSS_E_COMM_FAILURE); + goto err_exit; + } + + return TSS_SUCCESS; + +err_exit: + return result; +} + +/* XXX this should be moved out of an RPC-specific file */ +short +get_port(void) +{ + char *env_port; + int port = 0; + + env_port = getenv("TSS_TCSD_PORT"); + + if (env_port == NULL) + return TCSD_DEFAULT_PORT; + + port = atoi(env_port); + + if (port == 0 || port > 65535) + return TCSD_DEFAULT_PORT; + + return (short)port; +} + diff --git a/src/tspi/rpc/tcstp/rpc_admin.c b/src/tspi/rpc/tcstp/rpc_admin.c new file mode 100644 index 0000000..e29726e --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_admin.c @@ -0,0 +1,373 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_SetOwnerInstall_TP(struct host_table_entry *hte, + TSS_BOOL state) /* in */ +{ + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_SETOWNERINSTALL; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_BOOL, 1, &state, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + return result; +} + +TSS_RESULT +RPC_DisableOwnerClear_TP(struct host_table_entry *hte, + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_DISABLEOWNERCLEAR; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (setData(TCSD_PACKET_TYPE_AUTH, 1, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS ){ + if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +TSS_RESULT +RPC_ForceClear_TP(struct host_table_entry *hte) +{ + TSS_RESULT result; + + initData(&hte->comm, 1); + hte->comm.hdr.u.ordinal = TCSD_ORD_FORCECLEAR; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + return result; +} + +TSS_RESULT +RPC_DisableForceClear_TP(struct host_table_entry *hte) +{ + TSS_RESULT result; + + initData(&hte->comm, 1); + hte->comm.hdr.u.ordinal = TCSD_ORD_DISABLEFORCECLEAR; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + return result; +} + +TSS_RESULT +RPC_PhysicalDisable_TP(struct host_table_entry *hte) +{ + TSS_RESULT result; + + initData(&hte->comm, 1); + hte->comm.hdr.u.ordinal = TCSD_ORD_PHYSICALDISABLE; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + return result; +} + +TSS_RESULT +RPC_PhysicalEnable_TP(struct host_table_entry *hte) +{ + TSS_RESULT result; + + initData(&hte->comm, 1); + hte->comm.hdr.u.ordinal = TCSD_ORD_PHYSICALENABLE; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + return result; +} + +TSS_RESULT +RPC_OwnerSetDisable_TP(struct host_table_entry *hte, + TSS_BOOL disableState, /* in */ + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 3); + hte->comm.hdr.u.ordinal = TCSD_ORD_OWNERSETDISABLE; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_BOOL, 1, &disableState, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 2, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +TSS_RESULT +RPC_PhysicalSetDeactivated_TP(struct host_table_entry *hte, + TSS_BOOL state) /* in */ +{ + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_PHYSICALSETDEACTIVATED; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_BOOL, 1, &state, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + return result; +} + +TSS_RESULT +RPC_PhysicalPresence_TP(struct host_table_entry *hte, + TCPA_PHYSICAL_PRESENCE fPhysicalPresence) /* in */ +{ + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_PHYSICALPRESENCE; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT16, 1, &fPhysicalPresence, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + return result; +} + +TSS_RESULT +RPC_SetTempDeactivated_TP(struct host_table_entry *hte) +{ + TSS_RESULT result; + + initData(&hte->comm, 1); + hte->comm.hdr.u.ordinal = TCSD_ORD_SETTEMPDEACTIVATED; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + return result; +} + +#ifdef TSS_BUILD_TSS12 +TSS_RESULT +RPC_SetTempDeactivated2_TP(struct host_table_entry *hte, + TPM_AUTH *operatorAuth) /* in/out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_SETTEMPDEACTIVATED2; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (operatorAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 1, operatorAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } else { + TPM_AUTH nullAuth; + + memset(&nullAuth, 0, sizeof(TPM_AUTH)); + if (setData(TCSD_PACKET_TYPE_AUTH, 1, &nullAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (operatorAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, operatorAuth, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + + return result; +} +#endif + +TSS_RESULT +RPC_FieldUpgrade_TP(struct host_table_entry *hte, + UINT32 dataInSize, /* in */ + BYTE * dataIn, /* in */ + UINT32 * dataOutSize, /* out */ + BYTE ** dataOut, /* out */ + TPM_AUTH * ownerAuth) /* in, out */ +{ + return TSPERR(TSS_E_NOTIMPL); +} + +TSS_RESULT +RPC_SetRedirection_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE keyHandle, /* in */ + UINT32 c1, /* in */ + UINT32 c2, /* in */ + TPM_AUTH * privAuth) /* in, out */ +{ + return TSPERR(TSS_E_NOTIMPL); + +} + +#ifdef TSS_BUILD_TSS12 +TSS_RESULT +RPC_ResetLockValue_TP(struct host_table_entry *hte, + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_RESETLOCKVALUE; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 1, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +TSS_RESULT +RPC_FlushSpecific_TP(struct host_table_entry *hte, + TCS_HANDLE hResHandle, /* in */ + TPM_RESOURCE_TYPE resourceType) /* in */ +{ + TSS_RESULT result; + + initData(&hte->comm, 3); + hte->comm.hdr.u.ordinal = TCSD_ORD_FLUSHSPECIFIC; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hResHandle, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &resourceType, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + return result; +} +#endif diff --git a/src/tspi/rpc/tcstp/rpc_aik.c b/src/tspi/rpc/tcstp/rpc_aik.c new file mode 100644 index 0000000..cd40845 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_aik.c @@ -0,0 +1,336 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_MakeIdentity_TP(struct host_table_entry *hte, + TCPA_ENCAUTH identityAuth, /* in */ + TCPA_CHOSENID_HASH IDLabel_PrivCAHash, /* in */ + UINT32 idKeyInfoSize, /* in */ + BYTE * idKeyInfo, /* in */ + TPM_AUTH * pSrkAuth, /* in, out */ + TPM_AUTH * pOwnerAuth, /* in, out */ + UINT32 * idKeySize, /* out */ + BYTE ** idKey, /* out */ + UINT32 * pcIdentityBindingSize, /* out */ + BYTE ** prgbIdentityBinding, /* out */ + UINT32 * pcEndorsementCredentialSize, /* out */ + BYTE ** prgbEndorsementCredential, /* out */ + UINT32 * pcPlatformCredentialSize, /* out */ + BYTE ** prgbPlatformCredential, /* out */ + UINT32 * pcConformanceCredentialSize, /* out */ + BYTE ** prgbConformanceCredential) /* out */ +{ + TSS_RESULT result; + int i; + + initData(&hte->comm, 7); + hte->comm.hdr.u.ordinal = TCSD_ORD_MAKEIDENTITY; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_ENCAUTH, 1, &identityAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_DIGEST, 2, &IDLabel_PrivCAHash, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 3, &idKeyInfoSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 4, idKeyInfo, idKeyInfoSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + i = 5; + if (pSrkAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, i++, pSrkAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (setData(TCSD_PACKET_TYPE_AUTH, i++, pOwnerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + i = 0; + if (result == TSS_SUCCESS) { + i = 0; + if (pSrkAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, pSrkAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + if (getData(TCSD_PACKET_TYPE_AUTH, i++, pOwnerAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, idKeySize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *idKey = (BYTE *) malloc(*idKeySize); + if (*idKey == NULL) { + LogError("malloc of %u bytes failed.", *idKeySize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *idKey, *idKeySize, &hte->comm)) { + free(*idKey); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, pcIdentityBindingSize, 0, &hte->comm)) { + free(*idKey); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *prgbIdentityBinding = (BYTE *) malloc(*pcIdentityBindingSize); + if (*prgbIdentityBinding == NULL) { + LogError("malloc of %u bytes failed.", *pcIdentityBindingSize); + free(*idKey); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *prgbIdentityBinding, *pcIdentityBindingSize, &hte->comm)) { + free(*idKey); + free(*prgbIdentityBinding); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, pcEndorsementCredentialSize, 0, &hte->comm)) { + free(*idKey); + free(*prgbIdentityBinding); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *prgbEndorsementCredential = (BYTE *) malloc(*pcEndorsementCredentialSize); + if (*prgbEndorsementCredential == NULL) { + LogError("malloc of %u bytes failed.", *pcEndorsementCredentialSize); + free(*idKey); + free(*prgbIdentityBinding); + *prgbIdentityBinding = NULL; + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *prgbEndorsementCredential, *pcEndorsementCredentialSize, &hte->comm)) { + free(*idKey); + free(*prgbIdentityBinding); + *prgbIdentityBinding = NULL; + free(*prgbEndorsementCredential); + *prgbEndorsementCredential = NULL; + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, pcPlatformCredentialSize, 0, &hte->comm)) { + free(*idKey); + free(*prgbIdentityBinding); + *prgbIdentityBinding = NULL; + free(*prgbEndorsementCredential); + *prgbEndorsementCredential = NULL; + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *prgbPlatformCredential = (BYTE *) malloc(*pcPlatformCredentialSize); + if (*prgbPlatformCredential == NULL) { + LogError("malloc of %u bytes failed.", *pcPlatformCredentialSize); + free(*idKey); + free(*prgbIdentityBinding); + *prgbIdentityBinding = NULL; + free(*prgbEndorsementCredential); + *prgbEndorsementCredential = NULL; + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *prgbPlatformCredential, *pcPlatformCredentialSize, &hte->comm)) { + free(*idKey); + free(*prgbIdentityBinding); + *prgbIdentityBinding = NULL; + free(*prgbEndorsementCredential); + *prgbEndorsementCredential = NULL; + free(*prgbPlatformCredential); + *prgbPlatformCredential = NULL; + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, pcConformanceCredentialSize, 0, &hte->comm)) { + free(*idKey); + free(*prgbIdentityBinding); + *prgbIdentityBinding = NULL; + free(*prgbEndorsementCredential); + *prgbEndorsementCredential = NULL; + free(*prgbPlatformCredential); + *prgbPlatformCredential = NULL; + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *prgbConformanceCredential = (BYTE *) malloc(*pcConformanceCredentialSize); + if (*prgbConformanceCredential == NULL) { + LogError("malloc of %u bytes failed.", *pcConformanceCredentialSize); + free(*idKey); + free(*prgbIdentityBinding); + *prgbIdentityBinding = NULL; + free(*prgbEndorsementCredential); + *prgbEndorsementCredential = NULL; + free(*prgbPlatformCredential); + *prgbPlatformCredential = NULL; + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *prgbConformanceCredential, *pcConformanceCredentialSize, &hte->comm)) { + free(*idKey); + free(*prgbIdentityBinding); + *prgbIdentityBinding = NULL; + free(*prgbEndorsementCredential); + *prgbEndorsementCredential = NULL; + free(*prgbPlatformCredential); + *prgbPlatformCredential = NULL; + free(*prgbConformanceCredential); + *prgbConformanceCredential = NULL; + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + +done: + return result; +} + +TSS_RESULT +RPC_GetCredential_TP(struct host_table_entry *hte, + UINT32 ulCredentialType, /* in */ + UINT32 ulCredentialAccessMode, /* in */ + UINT32 * pulCredentialSize, /* out */ + BYTE ** prgbCredentialData) /* out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 3); + hte->comm.hdr.u.ordinal = TCSD_ORD_GETCREDENTIAL; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &ulCredentialType, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &ulCredentialAccessMode, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, pulCredentialSize, 0, &hte->comm)) { + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + *prgbCredentialData = (BYTE *) malloc(*pulCredentialSize); + if (*prgbCredentialData == NULL) { + LogError("malloc of %u bytes failed.", *pulCredentialSize); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *prgbCredentialData, + *pulCredentialSize, &hte->comm)) { + free(*prgbCredentialData); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + return result; +} + +TSS_RESULT +RPC_ActivateTPMIdentity_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE idKey, /* in */ + UINT32 blobSize, /* in */ + BYTE * blob, /* in */ + TPM_AUTH * idKeyAuth, /* in, out */ + TPM_AUTH * ownerAuth, /* in, out */ + UINT32 * SymmetricKeySize, /* out */ + BYTE ** SymmetricKey) /* out */ +{ + TSS_RESULT result; + int i = 0; + + initData(&hte->comm, 6); + hte->comm.hdr.u.ordinal = TCSD_ORD_ACTIVATETPMIDENTITY; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, i++, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, i++, &idKey, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, i++, &blobSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, i++, blob, blobSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (idKeyAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, i++, idKeyAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (setData(TCSD_PACKET_TYPE_AUTH, i++, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (idKeyAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, idKeyAuth, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + if (getData(TCSD_PACKET_TYPE_AUTH, i++, ownerAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, SymmetricKeySize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *SymmetricKey = malloc(*SymmetricKeySize); + if (*SymmetricKey == NULL) { + LogError("malloc of %u bytes failed.", *SymmetricKeySize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *SymmetricKey, *SymmetricKeySize, &hte->comm)) { + free(*SymmetricKey); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } +done: + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_audit.c b/src/tspi/rpc/tcstp/rpc_audit.c new file mode 100644 index 0000000..63cc0e2 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_audit.c @@ -0,0 +1,240 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_SetOrdinalAuditStatus_TP(struct host_table_entry *hte, + TPM_AUTH *ownerAuth, /* in/out */ + UINT32 ulOrdinal, /* in */ + TSS_BOOL bAuditState) /* in */ +{ + TSS_RESULT result; + + initData(&hte->comm, 4); + hte->comm.hdr.u.ordinal = TCSD_ORD_SETORDINALAUDITSTATUS; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &ulOrdinal, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_BOOL, 2, &bAuditState, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 3, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +TSS_RESULT +RPC_GetAuditDigest_TP(struct host_table_entry *hte, + UINT32 startOrdinal, /* in */ + TPM_DIGEST *auditDigest, /* out */ + UINT32 *counterValueSize, /* out */ + BYTE **counterValue, /* out */ + TSS_BOOL *more, /* out */ + UINT32 *ordSize, /* out */ + UINT32 **ordList) /* out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_GETAUDITDIGEST; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &startOrdinal, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_DIGEST, 0, auditDigest, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_UINT32, 1, counterValueSize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + *counterValue = (BYTE *)malloc(*counterValueSize); + if (*counterValue == NULL) { + LogError("malloc of %u bytes failed.", *counterValueSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 2, *counterValue, *counterValueSize, &hte->comm)) { + free(*counterValue); + *counterValue = NULL; + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_BOOL, 3, more, 0, &hte->comm)) { + free(*counterValue); + *counterValue = NULL; + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_UINT32, 4, ordSize, 0, &hte->comm)) { + free(*counterValue); + *counterValue = NULL; + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + *ordList = (UINT32 *)malloc(*ordSize * sizeof(UINT32)); + if (*ordList == NULL) { + LogError("malloc of %u bytes failed.", *ordSize); + free(*counterValue); + *counterValue = NULL; + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 5, *ordList, *ordSize * sizeof(UINT32), &hte->comm)) { + free(*counterValue); + *counterValue = NULL; + free(*ordList); + *ordList = NULL; + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + +done: + return result; +} + +TSS_RESULT +RPC_GetAuditDigestSigned_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE keyHandle, /* in */ + TSS_BOOL closeAudit, /* in */ + TPM_NONCE *antiReplay, /* in */ + TPM_AUTH *privAuth, /* in/out */ + UINT32 *counterValueSize, /* out */ + BYTE **counterValue, /* out */ + TPM_DIGEST *auditDigest, /* out */ + TPM_DIGEST *ordinalDigest, /* out */ + UINT32 *sigSize, /* out */ + BYTE **sig) /* out */ +{ + TSS_RESULT result; + TPM_AUTH null_auth; + int i; + + initData(&hte->comm, 5); + hte->comm.hdr.u.ordinal = TCSD_ORD_GETAUDITDIGESTSIGNED; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + memset(&null_auth, 0, sizeof(TPM_AUTH)); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &keyHandle, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_BOOL, 2, &closeAudit, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_NONCE, 3, antiReplay, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (privAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 4, privAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + else { + if (setData(TCSD_PACKET_TYPE_AUTH, 4, &null_auth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (privAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, privAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, counterValueSize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + *counterValue = (BYTE *)malloc(*counterValueSize); + if (*counterValue == NULL) { + LogError("malloc of %u bytes failed.", *counterValueSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *counterValue, *counterValueSize, &hte->comm)) { + free(*counterValue); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_DIGEST, i++, auditDigest, 0, &hte->comm)) { + free(*counterValue); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_DIGEST, i++, ordinalDigest, 0, &hte->comm)) { + free(*counterValue); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, sigSize, 0, &hte->comm)) { + free(*counterValue); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + *sig = (BYTE *)malloc(*sigSize); + if (*sig == NULL) { + LogError("malloc of %u bytes failed.", *sigSize); + free(*counterValue); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *sig, *sigSize, &hte->comm)) { + free(*counterValue); + free(*sig); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + +done: + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_auth.c b/src/tspi/rpc/tcstp/rpc_auth.c new file mode 100644 index 0000000..266d485 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_auth.c @@ -0,0 +1,96 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_OIAP_TP(struct host_table_entry *hte, + TCS_AUTHHANDLE * authHandle, /* out */ + TCPA_NONCE * nonce0 /* out */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 1); + hte->comm.hdr.u.ordinal = TCSD_ORD_OIAP; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, authHandle, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + if (getData(TCSD_PACKET_TYPE_NONCE, 1, nonce0, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +TSS_RESULT +RPC_OSAP_TP(struct host_table_entry *hte, + TCPA_ENTITY_TYPE entityType, /* in */ + UINT32 entityValue, /* in */ + TCPA_NONCE * nonceOddOSAP, /* in */ + TCS_AUTHHANDLE * authHandle, /* out */ + TCPA_NONCE * nonceEven, /* out */ + TCPA_NONCE * nonceEvenOSAP /* out */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 4); + hte->comm.hdr.u.ordinal = TCSD_ORD_OSAP; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT16, 1, &entityType, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &entityValue, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_NONCE, 3, nonceOddOSAP, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, authHandle, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + if (getData(TCSD_PACKET_TYPE_NONCE, 1, nonceEven, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + if (getData(TCSD_PACKET_TYPE_NONCE, 2, nonceEvenOSAP, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_bind.c b/src/tspi/rpc/tcstp/rpc_bind.c new file mode 100644 index 0000000..79d7588 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_bind.c @@ -0,0 +1,90 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_UnBind_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE keyHandle, /* in */ + UINT32 inDataSize, /* in */ + BYTE * inData, /* in */ + TPM_AUTH * privAuth, /* in, out */ + UINT32 * outDataSize, /* out */ + BYTE ** outData /* out */ + ) { + TSS_RESULT result; + int i; + + initData(&hte->comm, 5); + hte->comm.hdr.u.ordinal = TCSD_ORD_UNBIND; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &keyHandle, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &inDataSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 3, inData, inDataSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (privAuth != NULL) { + if (setData(TCSD_PACKET_TYPE_AUTH, 4, privAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (privAuth != NULL) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, privAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, outDataSize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *outData = (BYTE *) malloc(*outDataSize); + if (*outData == NULL) { + LogError("malloc of %u bytes failed.", *outDataSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *outData, *outDataSize, &hte->comm)) { + free(*outData); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + +done: + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_caps.c b/src/tspi/rpc/tcstp/rpc_caps.c new file mode 100644 index 0000000..b626c55 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_caps.c @@ -0,0 +1,76 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_GetCapability_TP(struct host_table_entry *hte, + TCPA_CAPABILITY_AREA capArea, /* in */ + UINT32 subCapSize, /* in */ + BYTE * subCap, /* in */ + UINT32 * respSize, /* out */ + BYTE ** resp) /* out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 4); + hte->comm.hdr.u.ordinal = TCSD_ORD_TCSGETCAPABILITY; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &capArea, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &subCapSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 3, subCap, subCapSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, respSize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *resp = (BYTE *) calloc_tspi(hte->tspContext, *respSize); + if (*resp == NULL) { + LogError("malloc of %u bytes failed.", *respSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *resp, *respSize, &hte->comm)) { + free_tspi(hte->tspContext, *resp); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + +done: + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_caps_tpm.c b/src/tspi/rpc/tcstp/rpc_caps_tpm.c new file mode 100644 index 0000000..8957529 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_caps_tpm.c @@ -0,0 +1,175 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_GetTPMCapability_TP(struct host_table_entry *hte, + TCPA_CAPABILITY_AREA capArea, /* in */ + UINT32 subCapSize, /* in */ + BYTE * subCap, /* in */ + UINT32 * respSize, /* out */ + BYTE ** resp) /* out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 4); + hte->comm.hdr.u.ordinal = TCSD_ORD_GETCAPABILITY; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &capArea, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &subCapSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 3, subCap, subCapSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, respSize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *resp = (BYTE *) malloc(*respSize); + if (*resp == NULL) { + LogError("malloc of %u bytes failed.", *respSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *resp, *respSize, &hte->comm)) { + free(*resp); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + +done: + return result; +} + +TSS_RESULT +RPC_GetCapabilitySigned_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE keyHandle, /* in */ + TCPA_NONCE antiReplay, /* in */ + TCPA_CAPABILITY_AREA capArea, /* in */ + UINT32 subCapSize, /* in */ + BYTE * subCap, /* in */ + TPM_AUTH * privAuth, /* in, out */ + TCPA_VERSION * Version, /* out */ + UINT32 * respSize, /* out */ + BYTE ** resp, /* out */ + UINT32 * sigSize, /* out */ + BYTE ** sig) /* out */ +{ + return TSPERR(TSS_E_NOTIMPL); +} + +TSS_RESULT +RPC_GetCapabilityOwner_TP(struct host_table_entry *hte, + TPM_AUTH * pOwnerAuth, /* out */ + TCPA_VERSION * pVersion, /* out */ + UINT32 * pNonVolatileFlags, /* out */ + UINT32 * pVolatileFlags) /* out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_GETCAPABILITYOWNER; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 1, pOwnerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_VERSION, 0, pVersion, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + if (getData(TCSD_PACKET_TYPE_UINT32, 1, pNonVolatileFlags, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + if (getData(TCSD_PACKET_TYPE_UINT32, 2, pVolatileFlags, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + if (getData(TCSD_PACKET_TYPE_AUTH, 3, pOwnerAuth, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +TSS_RESULT +RPC_SetCapability_TP(struct host_table_entry *hte, + TCPA_CAPABILITY_AREA capArea, /* in */ + UINT32 subCapSize, /* in */ + BYTE * subCap, /* in */ + UINT32 valueSize, /* in */ + BYTE * value, /* in */ + TPM_AUTH * pOwnerAuth) /* in, out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 7); + hte->comm.hdr.u.ordinal = TCSD_ORD_SETCAPABILITY; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &capArea, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &subCapSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 3, subCap, subCapSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 4, &valueSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 5, value, valueSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (pOwnerAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 6, pOwnerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, pOwnerAuth, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_certify.c b/src/tspi/rpc/tcstp/rpc_certify.c new file mode 100644 index 0000000..3568c94 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_certify.c @@ -0,0 +1,131 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_CertifyKey_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE certHandle, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + TPM_NONCE * antiReplay, /* in */ + TPM_AUTH * certAuth, /* in, out */ + TPM_AUTH * keyAuth, /* in, out */ + UINT32 * CertifyInfoSize, /* out */ + BYTE ** CertifyInfo, /* out */ + UINT32 * outDataSize, /* out */ + BYTE ** outData /* out */ + ) { + TSS_RESULT result; + TPM_AUTH null_auth; + int i; + + initData(&hte->comm, 6); + memset(&null_auth, 0, sizeof(TPM_AUTH)); + + hte->comm.hdr.u.ordinal = TCSD_ORD_CERTIFYKEY; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &certHandle, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &keyHandle, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_NONCE, 3, antiReplay, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (certAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 4, certAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } else { + if (setData(TCSD_PACKET_TYPE_AUTH, 4, &null_auth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (keyAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 5, keyAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } else { + if (setData(TCSD_PACKET_TYPE_AUTH, 5, &null_auth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (certAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, certAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + if (keyAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, keyAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, CertifyInfoSize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *CertifyInfo = (BYTE *) malloc(*CertifyInfoSize); + if (*CertifyInfo == NULL) { + LogError("malloc of %u bytes failed.", *CertifyInfoSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *CertifyInfo, *CertifyInfoSize, &hte->comm)) { + free(*CertifyInfo); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, outDataSize, 0, &hte->comm)) { + free(*CertifyInfo); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *outData = (BYTE *) malloc(*outDataSize); + if (*outData == NULL) { + LogError("malloc of %u bytes failed.", *outDataSize); + free(*CertifyInfo); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *outData, *outDataSize, &hte->comm)) { + free(*CertifyInfo); + free(*outData); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + +done: + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_changeauth.c b/src/tspi/rpc/tcstp/rpc_changeauth.c new file mode 100644 index 0000000..b4c3d87 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_changeauth.c @@ -0,0 +1,173 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_ChangeAuth_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE parentHandle, /* in */ + TCPA_PROTOCOL_ID protocolID, /* in */ + TCPA_ENCAUTH *newAuth, /* in */ + TCPA_ENTITY_TYPE entityType, /* in */ + UINT32 encDataSize, /* in */ + BYTE * encData, /* in */ + TPM_AUTH * ownerAuth, /* in, out */ + TPM_AUTH * entityAuth, /* in, out */ + UINT32 * outDataSize, /* out */ + BYTE ** outData) /* out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 9); + hte->comm.hdr.u.ordinal = TCSD_ORD_CHANGEAUTH; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &parentHandle, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT16, 2, &protocolID, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_ENCAUTH, 3, newAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT16, 4, &entityType, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 5, &encDataSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 6, encData, encDataSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 7, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 8, entityAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_AUTH, 1, entityAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_UINT32, 2, outDataSize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *outData = (BYTE *) malloc(*outDataSize); + if (*outData == NULL) { + LogError("malloc of %u bytes failed.", *outDataSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 3, *outData, *outDataSize, &hte->comm)) { + free(*outData); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + +done: + return result; +} + +TSS_RESULT +RPC_ChangeAuthOwner_TP(struct host_table_entry *hte, + TCPA_PROTOCOL_ID protocolID, /* in */ + TCPA_ENCAUTH *newAuth, /* in */ + TCPA_ENTITY_TYPE entityType, /* in */ + TPM_AUTH * ownerAuth /* in, out */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 5); + hte->comm.hdr.u.ordinal = TCSD_ORD_CHANGEAUTHOWNER; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT16, 1, &protocolID, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_ENCAUTH, 2, newAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT16, 3, &entityType, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 4, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (hte->comm.hdr.u.result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +TSS_RESULT +RPC_ChangeAuthAsymStart_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE idHandle, /* in */ + TCPA_NONCE antiReplay, /* in */ + UINT32 KeySizeIn, /* in */ + BYTE * KeyDataIn, /* in */ + TPM_AUTH * pAuth, /* in, out */ + UINT32 * KeySizeOut, /* out */ + BYTE ** KeyDataOut, /* out */ + UINT32 * CertifyInfoSize, /* out */ + BYTE ** CertifyInfo, /* out */ + UINT32 * sigSize, /* out */ + BYTE ** sig, /* out */ + TCS_KEY_HANDLE * ephHandle /* out */ + ) { + return TSPERR(TSS_E_NOTIMPL); +} + +TSS_RESULT +RPC_ChangeAuthAsymFinish_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE parentHandle, /* in */ + TCS_KEY_HANDLE ephHandle, /* in */ + TCPA_ENTITY_TYPE entityType, /* in */ + TCPA_HMAC newAuthLink, /* in */ + UINT32 newAuthSize, /* in */ + BYTE * encNewAuth, /* in */ + UINT32 encDataSizeIn, /* in */ + BYTE * encDataIn, /* in */ + TPM_AUTH * ownerAuth, /* in, out */ + UINT32 * encDataSizeOut, /* out */ + BYTE ** encDataOut, /* out */ + TCPA_SALT_NONCE * saltNonce, /* out */ + TCPA_DIGEST * changeProof /* out */ + ) { + return TSPERR(TSS_E_NOTIMPL); +} diff --git a/src/tspi/rpc/tcstp/rpc_cmk.c b/src/tspi/rpc/tcstp/rpc_cmk.c new file mode 100644 index 0000000..ef8dfd5 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_cmk.c @@ -0,0 +1,393 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_CMK_SetRestrictions_TP(struct host_table_entry *hte, + TSS_CMK_DELEGATE restriction, /* in */ + TPM_AUTH *ownerAuth) /* in, out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 3); + hte->comm.hdr.u.ordinal = TCSD_ORD_CMK_SETRESTRICTIONS; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &restriction, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 2, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +TSS_RESULT +RPC_CMK_ApproveMA_TP(struct host_table_entry *hte, + TPM_DIGEST migAuthorityDigest, /* in */ + TPM_AUTH *ownerAuth, /* in, out */ + TPM_HMAC *migAuthorityApproval) /* out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 3); + hte->comm.hdr.u.ordinal = TCSD_ORD_CMK_APPROVEMA; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_DIGEST, 1, &migAuthorityDigest, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 2, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (getData(TCSD_PACKET_TYPE_DIGEST, 1, migAuthorityApproval, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +TSS_RESULT +RPC_CMK_CreateKey_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE hWrappingKey, /* in */ + TPM_ENCAUTH *keyUsageAuth, /* in */ + TPM_HMAC *migAuthorityApproval, /* in */ + TPM_DIGEST *migAuthorityDigest, /* in */ + UINT32 *keyDataSize, /* in, out */ + BYTE **keyData, /* in, out */ + TPM_AUTH *pAuth) /* in, out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 8); + hte->comm.hdr.u.ordinal = TCSD_ORD_CMK_CREATEKEY; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hWrappingKey, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_ENCAUTH, 2, keyUsageAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_DIGEST, 3, migAuthorityApproval, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_DIGEST, 4, migAuthorityDigest, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 5, keyDataSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 6, *keyData, *keyDataSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (pAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 7, pAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } else { + TPM_AUTH nullAuth; + + memset(&nullAuth, 0, sizeof(TPM_AUTH)); + if (setData(TCSD_PACKET_TYPE_AUTH, 7, &nullAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + free(*keyData); + *keyData = NULL; + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, keyDataSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + *keyData = (BYTE *)malloc(*keyDataSize); + if (*keyData == NULL) { + LogError("malloc of %u bytes failed.", *keyDataSize); + return TSPERR(TSS_E_OUTOFMEMORY); + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *keyData, *keyDataSize, &hte->comm)) { + free(*keyData); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (pAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, 2, pAuth, 0, &hte->comm)) { + free(*keyData); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + } + } + + return result; +} + +TSS_RESULT +RPC_CMK_CreateTicket_TP(struct host_table_entry *hte, + UINT32 publicVerifyKeySize, /* in */ + BYTE *publicVerifyKey, /* in */ + TPM_DIGEST signedData, /* in */ + UINT32 sigValueSize, /* in */ + BYTE *sigValue, /* in */ + TPM_AUTH *ownerAuth, /* in, out */ + TPM_HMAC *sigTicket) /* out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 7); + hte->comm.hdr.u.ordinal = TCSD_ORD_CMK_CREATETICKET; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &publicVerifyKeySize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 2, publicVerifyKey, publicVerifyKeySize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_DIGEST, 3, &signedData, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 4, &sigValueSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 5, sigValue, sigValueSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 6, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (getData(TCSD_PACKET_TYPE_DIGEST, 1, sigTicket, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +TSS_RESULT +RPC_CMK_CreateBlob_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE hParentKey, /* in */ + TSS_MIGRATE_SCHEME migrationType, /* in */ + UINT32 migKeyAuthSize, /* in */ + BYTE *migKeyAuth, /* in */ + TPM_DIGEST pubSourceKeyDigest, /* in */ + UINT32 msaListSize, /* in */ + BYTE *msaList, /* in */ + UINT32 restrictTicketSize, /* in */ + BYTE *restrictTicket, /* in */ + UINT32 sigTicketSize, /* in */ + BYTE *sigTicket, /* in */ + UINT32 encDataSize, /* in */ + BYTE *encData, /* in */ + TPM_AUTH *pAuth, /* in, out */ + UINT32 *randomSize, /* out */ + BYTE **random, /* out */ + UINT32 *outDataSize, /* out */ + BYTE **outData) /* out */ +{ + TSS_RESULT result; + int i; + + initData(&hte->comm, 15); + hte->comm.hdr.u.ordinal = TCSD_ORD_CMK_CREATEBLOB; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hParentKey, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT16, 2, &migrationType, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 3, &migKeyAuthSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 4, migKeyAuth, migKeyAuthSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_DIGEST, 5, &pubSourceKeyDigest, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 6, &msaListSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 7, msaList, msaListSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 8, &restrictTicketSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 9, restrictTicket, restrictTicketSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 10, &sigTicketSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 11, sigTicket, sigTicketSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 12, &encDataSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 13, encData, encDataSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (pAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 14, pAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } else { + TPM_AUTH nullAuth; + + memset(&nullAuth, 0, sizeof(TPM_AUTH)); + if (setData(TCSD_PACKET_TYPE_AUTH, 14, &nullAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (pAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, pAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, randomSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + *random = (BYTE *)malloc(*randomSize); + if (*random == NULL) { + LogError("malloc of %u bytes failed.", *randomSize); + return TSPERR(TSS_E_OUTOFMEMORY); + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *random, *randomSize, &hte->comm)) { + free(*random); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, outDataSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + *outData = (BYTE *)malloc(*outDataSize); + if (*outData == NULL) { + LogError("malloc of %u bytes failed.", *outDataSize); + free(*random); + return TSPERR(TSS_E_OUTOFMEMORY); + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *outData, *outDataSize, &hte->comm)) { + free(*random); + free(*outData); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + } + + return result; +} + +TSS_RESULT +RPC_CMK_ConvertMigration_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE hParentHandle, /* in */ + TPM_CMK_AUTH restrictTicket, /* in */ + TPM_HMAC sigTicket, /* in */ + UINT32 keyDataSize, /* in */ + BYTE *keyData, /* in */ + UINT32 msaListSize, /* in */ + BYTE *msaList, /* in */ + UINT32 randomSize, /* in */ + BYTE *random, /* in */ + TPM_AUTH *pAuth, /* in, out */ + UINT32 *outDataSize, /* out */ + BYTE **outData) /* out */ +{ + TSS_RESULT result; + int i; + + initData(&hte->comm, 11); + hte->comm.hdr.u.ordinal = TCSD_ORD_CMK_CONVERTMIGRATION; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hParentHandle, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 2, &restrictTicket, sizeof(restrictTicket), &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_DIGEST, 3, &sigTicket, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 4, &keyDataSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 5, keyData, keyDataSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 6, &msaListSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 7, msaList, msaListSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 8, &randomSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 9, random, randomSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (pAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 10, pAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } else { + TPM_AUTH nullAuth; + + memset(&nullAuth, 0, sizeof(TPM_AUTH)); + if (setData(TCSD_PACKET_TYPE_AUTH, 10, &nullAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (pAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, pAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, outDataSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + *outData = (BYTE *)malloc(*outDataSize); + if (*outData == NULL) { + LogError("malloc of %u bytes failed.", *outDataSize); + return TSPERR(TSS_E_OUTOFMEMORY); + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *outData, *outDataSize, &hte->comm)) { + free(*outData); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + } + + return result; +} + diff --git a/src/tspi/rpc/tcstp/rpc_context.c b/src/tspi/rpc/tcstp/rpc_context.c new file mode 100644 index 0000000..95fafbe --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_context.c @@ -0,0 +1,80 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_OpenContext_TP(struct host_table_entry* hte, + UINT32* tpm_version, + TCS_CONTEXT_HANDLE* tcsContext) +{ + TSS_RESULT result; + + initData(&hte->comm, 0); + hte->comm.hdr.u.ordinal = TCSD_ORD_OPENCONTEXT; + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + LogDebugFn("Received TCS Context: 0x%x", *tcsContext); + + if (getData(TCSD_PACKET_TYPE_UINT32, 1, tpm_version, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +TSS_RESULT +RPC_CloseContext_TP(struct host_table_entry *hte) +{ + TSS_RESULT result; + + initData(&hte->comm, 1); + hte->comm.hdr.u.ordinal = TCSD_ORD_CLOSECONTEXT; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + return result; +} + +TSS_RESULT +RPC_FreeMemory_TP(struct host_table_entry *hte, + BYTE * pMemory) /* in */ +{ + free(pMemory); + + return TSS_SUCCESS; +} diff --git a/src/tspi/rpc/tcstp/rpc_counter.c b/src/tspi/rpc/tcstp/rpc_counter.c new file mode 100644 index 0000000..d6b2b37 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_counter.c @@ -0,0 +1,204 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_ReadCounter_TP(struct host_table_entry* hte, + TSS_COUNTER_ID idCounter, /* in */ + TPM_COUNTER_VALUE* counterValue) /* out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_READCOUNTER; + LogDebugFn("IN: TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &idCounter, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_COUNTER_VALUE, 0, counterValue, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +TSS_RESULT +RPC_CreateCounter_TP(struct host_table_entry* hte, + UINT32 LabelSize, /* in (=4) */ + BYTE* pLabel, /* in */ + TPM_ENCAUTH CounterAuth, /* in */ + TPM_AUTH* pOwnerAuth, /* in, out */ + TSS_COUNTER_ID* idCounter, /* out */ + TPM_COUNTER_VALUE* counterValue) /* out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 5); + hte->comm.hdr.u.ordinal = TCSD_ORD_CREATECOUNTER; + LogDebugFn("IN: TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &LabelSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 2, &pLabel, LabelSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_ENCAUTH, 3, &CounterAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 4, pOwnerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, pOwnerAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_UINT32, 1, idCounter, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_COUNTER_VALUE, 2, counterValue, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } +done: + return result; +} + +TSS_RESULT +RPC_IncrementCounter_TP(struct host_table_entry* hte, + TSS_COUNTER_ID idCounter, /* in */ + TPM_AUTH* pCounterAuth, /* in, out */ + TPM_COUNTER_VALUE* counterValue) /* out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 3); + hte->comm.hdr.u.ordinal = TCSD_ORD_INCREMENTCOUNTER; + LogDebugFn("IN: TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &idCounter, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 2, pCounterAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, pCounterAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_COUNTER_VALUE, 1, counterValue, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } +done: + return result; +} + +TSS_RESULT +RPC_ReleaseCounter_TP(struct host_table_entry* hte, + TSS_COUNTER_ID idCounter, /* in */ + TPM_AUTH* pCounterAuth) /* in, out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 3); + hte->comm.hdr.u.ordinal = TCSD_ORD_RELEASECOUNTER; + LogDebugFn("IN: TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &idCounter, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 2, pCounterAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, pCounterAuth, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +TSS_RESULT +RPC_ReleaseCounterOwner_TP(struct host_table_entry* hte, + TSS_COUNTER_ID idCounter, /* in */ + TPM_AUTH* pOwnerAuth) /* in, out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 3); + hte->comm.hdr.u.ordinal = TCSD_ORD_RELEASECOUNTEROWNER; + LogDebugFn("IN: TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &idCounter, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 2, pOwnerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, pOwnerAuth, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_daa.c b/src/tspi/rpc/tcstp/rpc_daa.c new file mode 100644 index 0000000..e48d30e --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_daa.c @@ -0,0 +1,184 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_DaaJoin_TP(struct host_table_entry *hte, + TPM_HANDLE handle, // in + BYTE stage, // in + UINT32 inputSize0, // in + BYTE* inputData0, // in + UINT32 inputSize1, // in + BYTE* inputData1, // in + TPM_AUTH* ownerAuth, // in/out + UINT32* outputSize, // out + BYTE** outputData) // out +{ + TSS_RESULT result; + UINT32 i; + + LogDebugFn("stage=%d", stage); + initData(&hte->comm, 8); + hte->comm.hdr.u.ordinal = TCSD_ORD_DAAJOIN; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &handle, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_BYTE, 2, &stage, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 3, &inputSize0, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + LogDebugFn("inputSize0=<network>=%d <host>=%d", inputSize0, inputSize0); + if (setData(TCSD_PACKET_TYPE_PBYTE, 4, inputData0, inputSize0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 5, &inputSize1, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + LogDebugFn("inputSize1=<network>=%d <host>=%d", inputSize1, inputSize1); + if (setData(TCSD_PACKET_TYPE_PBYTE, 6, inputData1, inputSize1, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if( ownerAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 7, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + LogDebugFn("getData outputSize"); + + if( ownerAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, ownerAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, outputSize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + *outputData = (BYTE *) malloc(*outputSize); + if (*outputData == NULL) { + LogError("malloc of %u bytes failed.", *outputSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + LogDebugFn("getData outputData (outputSize=%u)", *outputSize); + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *outputData, *outputSize, &hte->comm)) { + free(*outputData); + *outputData = NULL; + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + +done: + LogDebugFn("result=%u", result); + return result; +} + +TSS_RESULT +RPC_DaaSign_TP(struct host_table_entry *hte, + TPM_HANDLE handle, // in + BYTE stage, // in + UINT32 inputSize0, // in + BYTE* inputData0, // in + UINT32 inputSize1, // in + BYTE* inputData1, // in + TPM_AUTH* ownerAuth, // in/out + UINT32* outputSize, // out + BYTE** outputData) // out +{ + TSS_RESULT result; + UINT32 i; + + LogDebugFn("stage=%d", stage); + initData(&hte->comm, 8); + hte->comm.hdr.u.ordinal = TCSD_ORD_DAASIGN; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &handle, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_BYTE, 2, &stage, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 3, &inputSize0, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + LogDebugFn("inputSize0=<network>=%d <host>=%d", inputSize0, inputSize0); + if (setData(TCSD_PACKET_TYPE_PBYTE, 4, inputData0, inputSize0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 5, &inputSize1, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + LogDebugFn("inputSize1=<network>=%d <host>=%d", inputSize1, inputSize1); + if (setData(TCSD_PACKET_TYPE_PBYTE, 6, inputData1, inputSize1, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if( ownerAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 7, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + LogDebugFn("sendTCSDPacket: 0x%x", (int)hte); + result = sendTCSDPacket(hte); + // + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + // + if (result == TSS_SUCCESS) { + i = 0; + LogDebugFn("getData outputSize"); + + if( ownerAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, ownerAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, outputSize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + *outputData = (BYTE *) malloc(*outputSize); + if (*outputData == NULL) { + LogError("malloc of %u bytes failed.", *outputSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + LogDebugFn("getData outputData (outputSize=%d)", *outputSize); + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *outputData, *outputSize, &hte->comm)) { + free(*outputData); + *outputData = NULL; + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + +done: + LogDebugFn("result=%u", result); + return result; +} + diff --git a/src/tspi/rpc/tcstp/rpc_delegate.c b/src/tspi/rpc/tcstp/rpc_delegate.c new file mode 100644 index 0000000..d4b6ac2 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_delegate.c @@ -0,0 +1,452 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_Delegate_Manage_TP(struct host_table_entry *hte, + TPM_FAMILY_ID familyID, /* in */ + TPM_FAMILY_OPERATION opFlag, /* in */ + UINT32 opDataSize, /* in */ + BYTE *opData, /* in */ + TPM_AUTH *ownerAuth, /* in/out */ + UINT32 *retDataSize, /* out */ + BYTE **retData) /* out */ +{ + TSS_RESULT result; + int i; + + initData(&hte->comm, 6); + hte->comm.hdr.u.ordinal = TCSD_ORD_DELEGATE_MANAGE; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &familyID, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &opFlag, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 3, &opDataSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 4, opData, opDataSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (ownerAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 5, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } else { + TPM_AUTH nullAuth; + + memset(&nullAuth, 0, sizeof(TPM_AUTH)); + if (setData(TCSD_PACKET_TYPE_AUTH, 5, &nullAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (ownerAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, retDataSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + *retData = (BYTE *)malloc(*retDataSize); + if (*retData == NULL) { + LogError("malloc of %u bytes failed.", *retDataSize); + return TSPERR(TSS_E_OUTOFMEMORY); + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *retData, *retDataSize, &hte->comm)) { + free(*retData); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + } + + return result; +} + +TSS_RESULT +RPC_Delegate_CreateKeyDelegation_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE hKey, /* in */ + UINT32 publicInfoSize, /* in */ + BYTE *publicInfo, /* in */ + TPM_ENCAUTH *encDelAuth, /* in */ + TPM_AUTH *keyAuth, /* in/out */ + UINT32 *blobSize, /* out */ + BYTE **blob) /* out */ +{ + TSS_RESULT result; + int i; + + initData(&hte->comm, 8); + hte->comm.hdr.u.ordinal = TCSD_ORD_DELEGATE_CREATEKEYDELEGATION; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hKey, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &publicInfoSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 3, publicInfo, publicInfoSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_ENCAUTH, 4, encDelAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (keyAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 5, keyAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } else { + TPM_AUTH nullAuth; + + memset(&nullAuth, 0, sizeof(TPM_AUTH)); + if (setData(TCSD_PACKET_TYPE_AUTH, 5, &nullAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (keyAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, keyAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, blobSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + *blob = (BYTE *)malloc(*blobSize); + if (*blob == NULL) { + LogError("malloc of %u bytes failed.", *blobSize); + return TSPERR(TSS_E_OUTOFMEMORY); + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *blob, *blobSize, &hte->comm)) { + free(*blob); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + } + + return result; +} + +TSS_RESULT +RPC_Delegate_CreateOwnerDelegation_TP(struct host_table_entry *hte, + TSS_BOOL increment, /* in */ + UINT32 publicInfoSize, /* in */ + BYTE *publicInfo, /* in */ + TPM_ENCAUTH *encDelAuth, /* in */ + TPM_AUTH *ownerAuth, /* in/out */ + UINT32 *blobSize, /* out */ + BYTE **blob) /* out */ +{ + TSS_RESULT result; + int i; + + initData(&hte->comm, 8); + hte->comm.hdr.u.ordinal = TCSD_ORD_DELEGATE_CREATEOWNERDELEGATION; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_BOOL, 1, &increment, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &publicInfoSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 3, publicInfo, publicInfoSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_ENCAUTH, 4, encDelAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (ownerAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 5, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } else { + TPM_AUTH nullAuth; + + memset(&nullAuth, 0, sizeof(TPM_AUTH)); + if (setData(TCSD_PACKET_TYPE_AUTH, 5, &nullAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (ownerAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, blobSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + *blob = (BYTE *)malloc(*blobSize); + if (*blob == NULL) { + LogError("malloc of %u bytes failed.", *blobSize); + return TSPERR(TSS_E_OUTOFMEMORY); + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *blob, *blobSize, &hte->comm)) { + free(*blob); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + } + + return result; +} + +TSS_RESULT +RPC_Delegate_LoadOwnerDelegation_TP(struct host_table_entry *hte, + TPM_DELEGATE_INDEX index, /* in */ + UINT32 blobSize, /* in */ + BYTE *blob, /* in */ + TPM_AUTH *ownerAuth) /* in/out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 5); + hte->comm.hdr.u.ordinal = TCSD_ORD_DELEGATE_LOADOWNERDELEGATION; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &index, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &blobSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 3, blob, blobSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (ownerAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 4, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } else { + TPM_AUTH nullAuth; + + memset(&nullAuth, 0, sizeof(TPM_AUTH)); + if (setData(TCSD_PACKET_TYPE_AUTH, 4, &nullAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (ownerAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + } + + return result; +} + +TSS_RESULT +RPC_Delegate_ReadTable_TP(struct host_table_entry *hte, + UINT32 *familyTableSize, /* out */ + BYTE **familyTable, /* out */ + UINT32 *delegateTableSize, /* out */ + BYTE **delegateTable) /* out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 1); + hte->comm.hdr.u.ordinal = TCSD_ORD_DELEGATE_READTABLE; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, familyTableSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + *familyTable = (BYTE *)malloc(*familyTableSize); + if (*familyTable == NULL) { + LogError("malloc of %u bytes failed.", *familyTableSize); + return TSPERR(TSS_E_OUTOFMEMORY); + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *familyTable, *familyTableSize, &hte->comm)) { + free(*familyTable); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + if (getData(TCSD_PACKET_TYPE_UINT32, 2, delegateTableSize, 0, &hte->comm)) { + free(*familyTable); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + *delegateTable = (BYTE *)malloc(*delegateTableSize); + if (*delegateTable == NULL) { + free(*familyTable); + LogError("malloc of %u bytes failed.", *delegateTableSize); + return TSPERR(TSS_E_OUTOFMEMORY); + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 3, *delegateTable, *delegateTableSize, &hte->comm)) { + free(*familyTable); + free(*delegateTable); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + } + + return result; +} + +TSS_RESULT +RPC_Delegate_UpdateVerificationCount_TP(struct host_table_entry *hte, + UINT32 inputSize, /* in */ + BYTE *input, /* in */ + TPM_AUTH *ownerAuth, /* in/out */ + UINT32 *outputSize, /* out */ + BYTE **output) /* out */ +{ + TSS_RESULT result; + int i; + + initData(&hte->comm, 4); + hte->comm.hdr.u.ordinal = TCSD_ORD_DELEGATE_UPDATEVERIFICATIONCOUNT; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &inputSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 2, input, inputSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (ownerAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 3, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } else { + TPM_AUTH nullAuth; + + memset(&nullAuth, 0, sizeof(TPM_AUTH)); + if (setData(TCSD_PACKET_TYPE_AUTH, 3, &nullAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (ownerAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, outputSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + *output = (BYTE *)malloc(*outputSize); + if (*output == NULL) { + LogError("malloc of %u bytes failed.", *outputSize); + return TSPERR(TSS_E_OUTOFMEMORY); + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *output, *outputSize, &hte->comm)) { + free(*output); + output = NULL; + return TSPERR(TSS_E_INTERNAL_ERROR); + } + } + + return result; +} + +TSS_RESULT +RPC_Delegate_VerifyDelegation_TP(struct host_table_entry *hte, + UINT32 delegateSize, /* in */ + BYTE *delegate) /* in */ +{ + TSS_RESULT result; + + initData(&hte->comm, 3); + hte->comm.hdr.u.ordinal = TCSD_ORD_DELEGATE_VERIFYDELEGATION; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &delegateSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 2, delegate, delegateSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + return result; +} + +TSS_RESULT +RPC_DSAP_TP(struct host_table_entry *hte, + TPM_ENTITY_TYPE entityType, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + TPM_NONCE *nonceOddDSAP, /* in */ + UINT32 entityValueSize, /* in */ + BYTE * entityValue, /* in */ + TCS_AUTHHANDLE *authHandle, /* out */ + TPM_NONCE *nonceEven, /* out */ + TPM_NONCE *nonceEvenDSAP) /* out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 6); + hte->comm.hdr.u.ordinal = TCSD_ORD_DSAP; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT16, 1, &entityType, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &keyHandle, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_NONCE, 3, nonceOddDSAP, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 4, &entityValueSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 5, entityValue, entityValueSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, authHandle, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (getData(TCSD_PACKET_TYPE_NONCE, 1, nonceEven, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (getData(TCSD_PACKET_TYPE_NONCE, 2, nonceEvenDSAP, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_dir.c b/src/tspi/rpc/tcstp/rpc_dir.c new file mode 100644 index 0000000..12f2d4f --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_dir.c @@ -0,0 +1,89 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_DirWriteAuth_TP(struct host_table_entry *hte, + TCPA_DIRINDEX dirIndex, /* in */ + TCPA_DIRVALUE *newContents, /* in */ + TPM_AUTH * ownerAuth /* in, out */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 4); + hte->comm.hdr.u.ordinal = TCSD_ORD_DIRWRITEAUTH; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &dirIndex, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_DIGEST, 2, newContents, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 3, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +TSS_RESULT +RPC_DirRead_TP(struct host_table_entry *hte, + TCPA_DIRINDEX dirIndex, /* in */ + TCPA_DIRVALUE * dirValue /* out */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_DIRREAD; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &dirIndex, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (hte->comm.hdr.u.result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_DIGEST, 0, dirValue, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_ek.c b/src/tspi/rpc/tcstp/rpc_ek.c new file mode 100644 index 0000000..c95753d --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_ek.c @@ -0,0 +1,304 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_CreateEndorsementKeyPair_TP(struct host_table_entry *hte, + TCPA_NONCE antiReplay, /* in */ + UINT32 endorsementKeyInfoSize, /* in */ + BYTE * endorsementKeyInfo, /* in */ + UINT32 * endorsementKeySize, /* out */ + BYTE ** endorsementKey, /* out */ + TCPA_DIGEST * checksum /* out */ + ) { + + TSS_RESULT result; + + initData(&hte->comm, 4); + hte->comm.hdr.u.ordinal = TCSD_ORD_CREATEENDORSEMENTKEYPAIR; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_NONCE, 1, &antiReplay, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &endorsementKeyInfoSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 3, endorsementKeyInfo, endorsementKeyInfoSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, endorsementKeySize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *endorsementKey = (BYTE *) malloc(*endorsementKeySize); + if (*endorsementKey == NULL) { + LogError("malloc of %u bytes failed.", *endorsementKeySize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *endorsementKey, *endorsementKeySize, &hte->comm)) { + free(*endorsementKey); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_DIGEST, 2, &(checksum->digest), 0, &hte->comm)) { + free(*endorsementKey); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + +done: + return result; +} + +TSS_RESULT +RPC_ReadPubek_TP(struct host_table_entry *hte, + TCPA_NONCE antiReplay, /* in */ + UINT32 * pubEndorsementKeySize, /* out */ + BYTE ** pubEndorsementKey, /* out */ + TCPA_DIGEST * checksum /* out */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_READPUBEK; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + /* &hte->comm.numParms = 2; */ + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_NONCE, 1, &antiReplay, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, pubEndorsementKeySize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *pubEndorsementKey = (BYTE *) malloc(*pubEndorsementKeySize); + if (*pubEndorsementKey == NULL) { + LogError("malloc of %u bytes failed.", *pubEndorsementKeySize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *pubEndorsementKey, *pubEndorsementKeySize, &hte->comm)) { + free(*pubEndorsementKey); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_DIGEST, 2, &(checksum->digest), 0, &hte->comm)) { + free(*pubEndorsementKey); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } +done: + return result; +} + +TSS_RESULT +RPC_DisablePubekRead_TP(struct host_table_entry *hte, + TPM_AUTH * ownerAuth /* in, out */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_DISABLEPUBEKREAD; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (setData(TCSD_PACKET_TYPE_AUTH, 1, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +TSS_RESULT +RPC_OwnerReadPubek_TP(struct host_table_entry *hte, + TPM_AUTH * ownerAuth, /* in, out */ + UINT32 * pubEndorsementKeySize, /* out */ + BYTE ** pubEndorsementKey /* out */ + ) { + + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_OWNERREADPUBEK; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 1, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)){ + free(*pubEndorsementKey); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + if (getData(TCSD_PACKET_TYPE_UINT32, 1, pubEndorsementKeySize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *pubEndorsementKey = (BYTE *) malloc(*pubEndorsementKeySize); + if (*pubEndorsementKey == NULL) { + LogError("malloc of %u bytes failed.", *pubEndorsementKeySize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + if (getData(TCSD_PACKET_TYPE_PBYTE, 2, *pubEndorsementKey, *pubEndorsementKeySize, &hte->comm)) { + free(*pubEndorsementKey); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + +done: + return result; +} + +#ifdef TSS_BUILD_TSS12 +TSS_RESULT +RPC_CreateRevocableEndorsementKeyPair_TP(struct host_table_entry *hte, + TPM_NONCE antiReplay, /* in */ + UINT32 endorsementKeyInfoSize,/* in */ + BYTE * endorsementKeyInfo, /* in */ + TSS_BOOL genResetAuth, /* in */ + TPM_DIGEST * eKResetAuth, /* in, out */ + UINT32 * endorsementKeySize, /* out */ + BYTE ** endorsementKey, /* out */ + TPM_DIGEST * checksum) /* out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 6); + hte->comm.hdr.u.ordinal = TCSD_ORD_CREATEREVOCABLEENDORSEMENTKEYPAIR; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_NONCE, 1, &antiReplay, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &endorsementKeyInfoSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 3, endorsementKeyInfo, endorsementKeyInfoSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_BOOL, 4, &genResetAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_DIGEST, 5, eKResetAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_DIGEST, 0, &(eKResetAuth->digest), 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_UINT32, 1, endorsementKeySize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + *endorsementKey = (BYTE *) malloc(*endorsementKeySize); + if (*endorsementKey == NULL) { + LogError("malloc of %u bytes failed.", *endorsementKeySize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 2, *endorsementKey, *endorsementKeySize, &hte->comm)) { + free(*endorsementKey); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_DIGEST, 3, &(checksum->digest), 0, &hte->comm)) { + free(*endorsementKey); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + +done: + return result; +} + +TSS_RESULT +RPC_RevokeEndorsementKeyPair_TP(struct host_table_entry *hte, + TPM_DIGEST *EKResetAuth) /* in */ +{ + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_REVOKEENDORSEMENTKEYPAIR; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_DIGEST, 1, EKResetAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + return result; +} +#endif diff --git a/src/tspi/rpc/tcstp/rpc_evlog.c b/src/tspi/rpc/tcstp/rpc_evlog.c new file mode 100644 index 0000000..7256795 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_evlog.c @@ -0,0 +1,231 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_LogPcrEvent_TP(struct host_table_entry *hte, + TSS_PCR_EVENT Event, /* in */ + UINT32 * pNumber /* out */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_LOGPCREVENT; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (setData(TCSD_PACKET_TYPE_PCR_EVENT, 1, &Event, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, pNumber, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +TSS_RESULT +RPC_GetPcrEvent_TP(struct host_table_entry *hte, + UINT32 PcrIndex, /* in */ + UINT32 * pNumber, /* in, out */ + TSS_PCR_EVENT ** ppEvent /* out */ + ) { + TSS_RESULT result; + BYTE lengthOnly = (ppEvent == NULL) ? TRUE : FALSE; + + initData(&hte->comm, 4); + hte->comm.hdr.u.ordinal = TCSD_ORD_GETPCREVENT; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &PcrIndex, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (setData(TCSD_PACKET_TYPE_UINT32, 2, pNumber, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (setData(TCSD_PACKET_TYPE_BYTE, 3, &lengthOnly, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, pNumber, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + if (ppEvent) { + *ppEvent = malloc(sizeof(TSS_PCR_EVENT)); + if (*ppEvent == NULL) { + LogError("malloc of %zd bytes failed.", + sizeof(TSS_PCR_EVENT)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + if (getData(TCSD_PACKET_TYPE_PCR_EVENT, 1, *ppEvent, 0, &hte->comm)) { + free(*ppEvent); + *ppEvent = NULL; + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + } + +done: + return result; +} + +TSS_RESULT +RPC_GetPcrEventsByPcr_TP(struct host_table_entry *hte, + UINT32 PcrIndex, /* in */ + UINT32 FirstEvent, /* in */ + UINT32 * pEventCount, /* in, out */ + TSS_PCR_EVENT ** ppEvents /* out */ + ) { + TSS_RESULT result; + UINT32 i, j; + + initData(&hte->comm, 4); + hte->comm.hdr.u.ordinal = TCSD_ORD_GETPCREVENTBYPCR; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &PcrIndex, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &FirstEvent, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (setData(TCSD_PACKET_TYPE_UINT32, 3, pEventCount, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, pEventCount, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + if (*pEventCount > 0) { + *ppEvents = calloc_tspi(hte->tspContext, + sizeof(TSS_PCR_EVENT) * (*pEventCount)); + if (*ppEvents == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(TSS_PCR_EVENT) * (*pEventCount)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + i = 1; + for (j = 0; j < (*pEventCount); j++) { + if (getData(TCSD_PACKET_TYPE_PCR_EVENT, i++, &((*ppEvents)[j]), 0, &hte->comm)) { + free(*ppEvents); + *ppEvents = NULL; + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + } else { + *ppEvents = NULL; + } + } + +done: + return result; +} + +TSS_RESULT +RPC_GetPcrEventLog_TP(struct host_table_entry *hte, + UINT32 * pEventCount, /* out */ + TSS_PCR_EVENT ** ppEvents /* out */ + ) { + TSS_RESULT result; + int i, j; + + initData(&hte->comm, 1); + hte->comm.hdr.u.ordinal = TCSD_ORD_GETPCREVENTLOG; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, pEventCount, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + if (*pEventCount > 0) { + *ppEvents = calloc_tspi(hte->tspContext, + sizeof(TSS_PCR_EVENT) * (*pEventCount)); + if (*ppEvents == NULL) { + LogError("malloc of %zd bytes failed.", + sizeof(TSS_PCR_EVENT) * (*pEventCount)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + i = 1; + for (j = 0; (UINT32)j < (*pEventCount); j++) { + if (getData(TCSD_PACKET_TYPE_PCR_EVENT, i++, &((*ppEvents)[j]), 0, &hte->comm)) { + free(*ppEvents); + *ppEvents = NULL; + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + } else { + *ppEvents = NULL; + } + } + +done: + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_key.c b/src/tspi/rpc/tcstp/rpc_key.c new file mode 100644 index 0000000..0c983af --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_key.c @@ -0,0 +1,350 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_LoadKeyByBlob_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE hUnwrappingKey, /* in */ + UINT32 cWrappedKeyBlobSize, /* in */ + BYTE * rgbWrappedKeyBlob, /* in */ + TPM_AUTH * pAuth, /* in, out */ + TCS_KEY_HANDLE * phKeyTCSI, /* out */ + TCS_KEY_HANDLE * phKeyHMAC) /* out */ +{ + TSS_RESULT result; + int i; + + initData(&hte->comm, 5); + hte->comm.hdr.u.ordinal = TCSD_ORD_LOADKEYBYBLOB; + LogDebugFn("IN: TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hUnwrappingKey, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &cWrappedKeyBlobSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 3, rgbWrappedKeyBlob, cWrappedKeyBlobSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (pAuth != NULL) { + if (setData(TCSD_PACKET_TYPE_AUTH, 4, pAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (pAuth != NULL) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, pAuth, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, phKeyTCSI, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + if (getData(TCSD_PACKET_TYPE_UINT32, i++, phKeyHMAC, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + + LogDebugFn("OUT: TCS key handle: 0x%x, TPM key slot: 0x%x", *phKeyTCSI, + *phKeyHMAC); + } + + return result; +} + +TSS_RESULT +RPC_EvictKey_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE hKey) /* in */ +{ + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_EVICTKEY; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hKey, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + return result; +} + +TSS_RESULT +RPC_CreateWrapKey_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE hWrappingKey, /* in */ + TCPA_ENCAUTH *KeyUsageAuth, /* in */ + TCPA_ENCAUTH *KeyMigrationAuth, /* in */ + UINT32 keyInfoSize, /* in */ + BYTE * keyInfo, /* in */ + UINT32 * keyDataSize, /* out */ + BYTE ** keyData, /* out */ + TPM_AUTH * pAuth) /* in, out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 7); + hte->comm.hdr.u.ordinal = TCSD_ORD_CREATEWRAPKEY; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hWrappingKey, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_ENCAUTH, 2, KeyUsageAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_ENCAUTH, 3, KeyMigrationAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 4, &keyInfoSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 5, keyInfo, keyInfoSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (pAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 6, pAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, keyDataSize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + *keyData = (BYTE *) malloc(*keyDataSize); + if (*keyData == NULL) { + LogError("malloc of %u bytes failed.", *keyDataSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *keyData, *keyDataSize, &hte->comm)) { + free(*keyData); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (pAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, 2, pAuth, 0, &hte->comm)) { + free(*keyData); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + } + +done: + return result; +} + +TSS_RESULT +RPC_GetPubKey_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE hKey, /* in */ + TPM_AUTH * pAuth, /* in, out */ + UINT32 * pcPubKeySize, /* out */ + BYTE ** prgbPubKey) /* out */ +{ + TSS_RESULT result; + int i; + + initData(&hte->comm, 3); + hte->comm.hdr.u.ordinal = TCSD_ORD_GETPUBKEY; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hKey, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (pAuth != NULL) { + if (setData(TCSD_PACKET_TYPE_AUTH, 2, pAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + i = 0; + if (result == TSS_SUCCESS) { + if (pAuth != NULL) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, pAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, pcPubKeySize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *prgbPubKey = (BYTE *) malloc(*pcPubKeySize); + if (*prgbPubKey == NULL) { + LogError("malloc of %u bytes failed.", *pcPubKeySize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *prgbPubKey, *pcPubKeySize, &hte->comm)) { + free(*prgbPubKey); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + +done: + return result; +} + +TSS_RESULT +RPC_TerminateHandle_TP(struct host_table_entry *hte, + TCS_AUTHHANDLE handle) /* in */ +{ + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_TERMINATEHANDLE; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &handle, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + return result; +} + +TSS_RESULT +RPC_OwnerReadInternalPub_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE hKey, /* in */ + TPM_AUTH * pOwnerAuth, /* in, out */ + UINT32 * punPubKeySize, /* out */ + BYTE ** ppbPubKeyData) /* out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 3); + hte->comm.hdr.u.ordinal = TCSD_ORD_OWNERREADINTERNALPUB; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hKey, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (pOwnerAuth != NULL) { + if (setData(TCSD_PACKET_TYPE_AUTH, 2, pOwnerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, pOwnerAuth, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + if (getData(TCSD_PACKET_TYPE_UINT32, 1, punPubKeySize, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + + *ppbPubKeyData = (BYTE *) malloc(*punPubKeySize); + if (*ppbPubKeyData == NULL) { + LogError("malloc of %u bytes failed.", *punPubKeySize); + return TSPERR(TSS_E_OUTOFMEMORY); + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 2, *ppbPubKeyData, *punPubKeySize, + &hte->comm)) { + free(*ppbPubKeyData); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + + return result; +} + +/* TSS 1.2-only interfaces */ +#ifdef TSS_BUILD_TSS12 +TSS_RESULT +RPC_KeyControlOwner_TP(struct host_table_entry *hte, // in + TCS_KEY_HANDLE hKey, // in + UINT32 ulPublicInfoLength, // in + BYTE* rgbPublicInfo, // in + UINT32 attribName, // in + TSS_BOOL attribValue, // in + TPM_AUTH* pOwnerAuth, // in, out + TSS_UUID* pUuidData) // out + +{ + TSS_RESULT result; + + initData(&hte->comm, 7); + hte->comm.hdr.u.ordinal = TCSD_ORD_KEYCONTROLOWNER; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hKey, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &ulPublicInfoLength, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 3, rgbPublicInfo, ulPublicInfoLength, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 4, &attribName, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_BOOL, 5, &attribValue, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (pOwnerAuth != NULL) { + if (setData(TCSD_PACKET_TYPE_AUTH, 6, pOwnerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, pOwnerAuth, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + if (getData(TCSD_PACKET_TYPE_UUID, 1, pUuidData, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} +#endif diff --git a/src/tspi/rpc/tcstp/rpc_maint.c b/src/tspi/rpc/tcstp/rpc_maint.c new file mode 100644 index 0000000..75dfc09 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_maint.c @@ -0,0 +1,250 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_CreateMaintenanceArchive_TP(struct host_table_entry *hte, + TSS_BOOL generateRandom, /* in */ + TPM_AUTH * ownerAuth, /* in, out */ + UINT32 * randomSize, /* out */ + BYTE ** random, /* out */ + UINT32 * archiveSize, /* out */ + BYTE ** archive /* out */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 3); + hte->comm.hdr.u.ordinal = TCSD_ORD_CREATEMAINTENANCEARCHIVE; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_BOOL, 1, &generateRandom, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 2, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + if (getData(TCSD_PACKET_TYPE_UINT32, 1, randomSize, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + + if (*randomSize > 0) { + *random = malloc(*randomSize); + if (*random == NULL) { + LogError("malloc of %u bytes failed.", *randomSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + if (getData(TCSD_PACKET_TYPE_PBYTE, 2, *random, *randomSize, &hte->comm)) { + free(*random); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } else { + *random = NULL; + } + + /* Assume all elements are in the list, even when *randomSize == 0. */ + if (getData(TCSD_PACKET_TYPE_UINT32, 3, archiveSize, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + + if (*archiveSize > 0) { + *archive = malloc(*archiveSize); + if (*archive == NULL) { + free(*random); + LogError("malloc of %u bytes failed.", *archiveSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + if (getData(TCSD_PACKET_TYPE_PBYTE, 4, *archive, *archiveSize, &hte->comm)) { + free(*random); + free(*archive); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } else { + *archive = NULL; + } + } +done: + return result; +} + +TSS_RESULT +RPC_LoadMaintenanceArchive_TP(struct host_table_entry *hte, + UINT32 dataInSize, /* in */ + BYTE * dataIn, /* in */ + TPM_AUTH * ownerAuth, /* in, out */ + UINT32 * dataOutSize, /* out */ + BYTE ** dataOut /* out */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 4); + hte->comm.hdr.u.ordinal = TCSD_ORD_LOADMAINTENANCEARCHIVE; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &dataInSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 2, &dataIn, dataInSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 3, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + if (getData(TCSD_PACKET_TYPE_UINT32, 1, dataOutSize, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + + if (*dataOutSize > 0) { + *dataOut = malloc(*dataOutSize); + if (*dataOut == NULL) { + LogError("malloc of %u bytes failed.", *dataOutSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + if (getData(TCSD_PACKET_TYPE_PBYTE, 2, *dataOut, *dataOutSize, &hte->comm)) { + free(*dataOut); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } else { + *dataOut = NULL; + } + } +done: + return result; +} + +TSS_RESULT +RPC_KillMaintenanceFeature_TP(struct host_table_entry *hte, + TPM_AUTH * ownerAuth /* in , out */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_KILLMAINTENANCEFEATURE; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 1, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +TSS_RESULT +RPC_LoadManuMaintPub_TP(struct host_table_entry *hte, + TCPA_NONCE antiReplay, /* in */ + UINT32 PubKeySize, /* in */ + BYTE * PubKey, /* in */ + TCPA_DIGEST * checksum /* out */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 4); + hte->comm.hdr.u.ordinal = TCSD_ORD_LOADMANUFACTURERMAINTENANCEPUB; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_NONCE, 1, &antiReplay, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &PubKeySize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 3, PubKey, PubKeySize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_DIGEST, 0, checksum, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +TSS_RESULT +RPC_ReadManuMaintPub_TP(struct host_table_entry *hte, + TCPA_NONCE antiReplay, /* in */ + TCPA_DIGEST * checksum /* out */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_READMANUFACTURERMAINTENANCEPUB; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_NONCE, 1, &antiReplay, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_DIGEST, 0, checksum, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_migration.c b/src/tspi/rpc/tcstp/rpc_migration.c new file mode 100644 index 0000000..43f7f27 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_migration.c @@ -0,0 +1,270 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_CreateMigrationBlob_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE parentHandle, /* in */ + TSS_MIGRATE_SCHEME migrationType, /* in */ + UINT32 MigrationKeyAuthSize, /* in */ + BYTE * MigrationKeyAuth, /* in */ + UINT32 encDataSize, /* in */ + BYTE * encData, /* in */ + TPM_AUTH * parentAuth, /* in, out */ + TPM_AUTH * entityAuth, /* in, out */ + UINT32 * randomSize, /* out */ + BYTE ** random, /* out */ + UINT32 * outDataSize, /* out */ + BYTE ** outData /* out */ + ) { + TSS_RESULT result; + TPM_AUTH null_auth; + UINT32 i; + + initData(&hte->comm, 9); + memset(&null_auth, 0, sizeof(TPM_AUTH)); + + hte->comm.hdr.u.ordinal = TCSD_ORD_CREATEMIGRATIONBLOB; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + i = 0; + if (setData(TCSD_PACKET_TYPE_UINT32, i++, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, i++, &parentHandle, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT16, i++, &migrationType, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, i++, &MigrationKeyAuthSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, i++, MigrationKeyAuth, MigrationKeyAuthSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, i++, &encDataSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, i++, encData, encDataSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (parentAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, i++, parentAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + if (setData(TCSD_PACKET_TYPE_AUTH, i++, entityAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (parentAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, parentAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + if (getData(TCSD_PACKET_TYPE_AUTH, i++, entityAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + if (getData(TCSD_PACKET_TYPE_UINT32, i++, randomSize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + if (*randomSize > 0) { + *random = (BYTE *)malloc(*randomSize); + if (*random == NULL) { + LogError("malloc of %u bytes failed.", *randomSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *random, *randomSize, &hte->comm)) { + free(*random); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + + if (getData(TCSD_PACKET_TYPE_UINT32, i++, outDataSize, 0, &hte->comm)) { + if (*randomSize > 0) + free(*random); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *outData = (BYTE *)malloc(*outDataSize); + if (*outData == NULL) { + if (*randomSize > 0) + free(*random); + LogError("malloc of %u bytes failed.", *outDataSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *outData, *outDataSize, &hte->comm)) { + if (*randomSize > 0) + free(*random); + free(*outData); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + +done: + return result; +} + +TSS_RESULT +RPC_ConvertMigrationBlob_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE parentHandle, /* in */ + UINT32 inDataSize, /* in */ + BYTE * inData, /* in */ + UINT32 randomSize, /* in */ + BYTE * random, /* in */ + TPM_AUTH * parentAuth, /* in, out */ + UINT32 * outDataSize, /* out */ + BYTE ** outData /* out */ + ) { + TSS_RESULT result; + UINT32 i; + + initData(&hte->comm, 7); + hte->comm.hdr.u.ordinal = TCSD_ORD_CONVERTMIGRATIONBLOB; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &parentHandle, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &inDataSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 3, inData, inDataSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 4, &randomSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 5, random, randomSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (parentAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 6, parentAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (parentAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, parentAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + + if (getData(TCSD_PACKET_TYPE_UINT32, i++, outDataSize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *outData = (BYTE *)malloc(*outDataSize); + if (*outData == NULL) { + LogError("malloc of %u bytes failed.", *outDataSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *outData, *outDataSize, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + +done: + return result; +} + +TSS_RESULT +RPC_AuthorizeMigrationKey_TP(struct host_table_entry *hte, + TSS_MIGRATE_SCHEME migrateScheme, /* in */ + UINT32 MigrationKeySize, /* in */ + BYTE * MigrationKey, /* in */ + TPM_AUTH * ownerAuth, /* in, out */ + UINT32 * MigrationKeyAuthSize, /* out */ + BYTE ** MigrationKeyAuth /* out */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 5); + hte->comm.hdr.u.ordinal = TCSD_ORD_AUTHORIZEMIGRATIONKEY; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT16, 1, &migrateScheme, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &MigrationKeySize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 3, MigrationKey, MigrationKeySize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 4, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_UINT32, 1, MigrationKeyAuthSize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *MigrationKeyAuth = (BYTE *)malloc(*MigrationKeyAuthSize); + if (*MigrationKeyAuth == NULL) { + LogError("malloc of %u bytes failed.", *MigrationKeyAuthSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 2, *MigrationKeyAuth, *MigrationKeyAuthSize, + &hte->comm)) { + free(*MigrationKeyAuth); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + +done: + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_nv.c b/src/tspi/rpc/tcstp/rpc_nv.c new file mode 100644 index 0000000..faf44e5 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_nv.c @@ -0,0 +1,315 @@ +/* + * The Initial Developer of the Original Code is Intel Corporation. + * Portions created by Intel Corporation are Copyright (C) 2007 Intel Corporation. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Common Public License as published by + * IBM Corporation; either version 1 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Common Public License for more details. + * + * You should have received a copy of the Common Public License + * along with this program; if not, a copy can be viewed at + * http://www.opensource.org/licenses/cpl1.0.php. + * + * trousers - An open source TCG Software Stack + * + * Author: james.xu@intel.com Rossey.liu@intel.com + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + +TSS_RESULT +RPC_NV_DefineOrReleaseSpace_TP(struct host_table_entry *hte, /* in */ + UINT32 cPubInfoSize, /* in */ + BYTE* pPubInfo, /* in */ + TCPA_ENCAUTH encAuth, /* in */ + TPM_AUTH* pAuth) /* in,out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 5); + hte->comm.hdr.u.ordinal = TCSD_ORD_NVDEFINEORRELEASESPACE; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &cPubInfoSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 2, pPubInfo, cPubInfoSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_ENCAUTH, 3, &encAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if( pAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 4, pAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + LogDebugFn("getData outputSize"); + + if( pAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, pAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + } + +done: + LogDebugFn("result=%u", result); + return result; +} + +TSS_RESULT +RPC_NV_WriteValue_TP(struct host_table_entry *hte, /* in */ + TSS_NV_INDEX hNVStore, /* in */ + UINT32 offset, /* in */ + UINT32 ulDataLength, /* in */ + BYTE* rgbDataToWrite, /* in */ + TPM_AUTH* privAuth) /* in,out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 6); + hte->comm.hdr.u.ordinal = TCSD_ORD_NVWRITEVALUE; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hNVStore, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &offset, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 3, &ulDataLength, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 4, rgbDataToWrite, ulDataLength, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if( privAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 5, privAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + LogDebugFn("getData outputSize"); + + if( privAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, privAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + } + +done: + LogDebugFn("result=%u", result); + return result; +} + +TSS_RESULT +RPC_NV_WriteValueAuth_TP(struct host_table_entry *hte, /* in */ + TSS_NV_INDEX hNVStore, /* in */ + UINT32 offset, /* in */ + UINT32 ulDataLength, /* in */ + BYTE* rgbDataToWrite, /* in */ + TPM_AUTH* NVAuth) /* in,out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 6); + hte->comm.hdr.u.ordinal = TCSD_ORD_NVWRITEVALUEAUTH; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hNVStore, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &offset, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 3, &ulDataLength, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 4, rgbDataToWrite, ulDataLength, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if( NVAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 5, NVAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + LogDebugFn("getData outputSize"); + + if( NVAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, NVAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + } + +done: + LogDebugFn("result=%u", result); + return result; +} + +TSS_RESULT +RPC_NV_ReadValue_TP(struct host_table_entry *hte, /* in */ + TSS_NV_INDEX hNVStore, /* in */ + UINT32 offset, /* in */ + UINT32* pulDataLength, /* in,out */ + TPM_AUTH* privAuth, /* in,out */ + BYTE** rgbDataRead) /* out */ +{ + TSS_RESULT result; + UINT32 i; + + initData(&hte->comm, 5); + hte->comm.hdr.u.ordinal = TCSD_ORD_NVREADVALUE; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hNVStore, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &offset, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 3, pulDataLength, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + LogDebugFn("SetData privAuth\n"); + if( privAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 4, privAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + LogDebugFn("Send data.\n"); + result = sendTCSDPacket(hte); + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + LogDebugFn("result=%u", result); + if (result == TSS_SUCCESS) { + i = 0; + LogDebugFn("getData outputSize"); + + if( privAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, privAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, pulDataLength, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + *rgbDataRead = (BYTE *) malloc(*pulDataLength); + if (*rgbDataRead == NULL) { + LogError("malloc of %u bytes failed.", *pulDataLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + LogDebugFn("getData rgbDataRead (pulDataLength=%u)", *pulDataLength); + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *rgbDataRead, *pulDataLength, &hte->comm)) { + free(*rgbDataRead); + *rgbDataRead = NULL; + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + +done: + LogDebugFn("result=%u", result); + return result; +} + +TSS_RESULT +RPC_NV_ReadValueAuth_TP(struct host_table_entry *hte, /* in */ + TSS_NV_INDEX hNVStore, /* in */ + UINT32 offset, /* in */ + UINT32* pulDataLength, /* in,out */ + TPM_AUTH* NVAuth, /* in,out */ + BYTE** rgbDataRead) /* out */ +{ + TSS_RESULT result; + UINT32 i; + + initData(&hte->comm, 5); + hte->comm.hdr.u.ordinal = TCSD_ORD_NVREADVALUEAUTH; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hNVStore, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &offset, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 3, pulDataLength, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if( NVAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 4, NVAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + LogDebugFn("getData outputSize"); + + if( NVAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, NVAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, pulDataLength, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + *rgbDataRead = (BYTE *) malloc(*pulDataLength); + if (*rgbDataRead == NULL) { + LogError("malloc of %u bytes failed.", *pulDataLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + LogDebugFn("getData rgbDataRead (pulDataLength=%u)", *pulDataLength); + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *rgbDataRead, *pulDataLength, &hte->comm)) { + free(*rgbDataRead); + *rgbDataRead = NULL; + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + +done: + LogDebugFn("result=%u", result); + return result; +} + diff --git a/src/tspi/rpc/tcstp/rpc_oper.c b/src/tspi/rpc/tcstp/rpc_oper.c new file mode 100644 index 0000000..3795aab --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_oper.c @@ -0,0 +1,47 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_SetOperatorAuth_TP(struct host_table_entry *hte, + TCPA_SECRET *operatorAuth) /* in */ +{ + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_SETOPERATORAUTH; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_SECRET, 1, operatorAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + return result; +} + diff --git a/src/tspi/rpc/tcstp/rpc_own.c b/src/tspi/rpc/tcstp/rpc_own.c new file mode 100644 index 0000000..7d06ca2 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_own.c @@ -0,0 +1,125 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_TakeOwnership_TP(struct host_table_entry *hte, + UINT16 protocolID, /* in */ + UINT32 encOwnerAuthSize, /* in */ + BYTE * encOwnerAuth, /* in */ + UINT32 encSrkAuthSize, /* in */ + BYTE * encSrkAuth, /* in */ + UINT32 srkInfoSize, /* in */ + BYTE * srkInfo, /* in */ + TPM_AUTH * ownerAuth, /* in, out */ + UINT32 * srkKeySize, + BYTE ** srkKey) +{ + TSS_RESULT result; + + initData(&hte->comm, 9); + hte->comm.hdr.u.ordinal = TCSD_ORD_TAKEOWNERSHIP; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT16, 1, &protocolID, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &encOwnerAuthSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 3, encOwnerAuth, encOwnerAuthSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 4, &encSrkAuthSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 5, encSrkAuth, encSrkAuthSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 6, &srkInfoSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 7, srkInfo, srkInfoSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_AUTH, 8, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_UINT32, 1, srkKeySize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *srkKey = (BYTE *) malloc(*srkKeySize); + if (*srkKey == NULL) { + LogError("malloc of %u bytes failed.", *srkKeySize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 2, *srkKey, *srkKeySize, &hte->comm)) { + free(*srkKey); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + +done: + return result; +} + + +TSS_RESULT +RPC_OwnerClear_TP(struct host_table_entry *hte, + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_OWNERCLEAR; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (setData(TCSD_PACKET_TYPE_AUTH, 1, ownerAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS ){ + if (getData(TCSD_PACKET_TYPE_AUTH, 0, ownerAuth, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_pcr_extend.c b/src/tspi/rpc/tcstp/rpc_pcr_extend.c new file mode 100644 index 0000000..3e97ad1 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_pcr_extend.c @@ -0,0 +1,113 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_Extend_TP(struct host_table_entry *hte, + TCPA_PCRINDEX pcrNum, /* in */ + TCPA_DIGEST inDigest, /* in */ + TCPA_PCRVALUE * outDigest /* out */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 3); + hte->comm.hdr.u.ordinal = TCSD_ORD_EXTEND; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &pcrNum, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_DIGEST, 2, &inDigest, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_DIGEST, 0, outDigest, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +TSS_RESULT +RPC_PcrRead_TP(struct host_table_entry *hte, + TCPA_PCRINDEX pcrNum, /* in */ + TCPA_PCRVALUE * outDigest /* out */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_PCRREAD; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &pcrNum, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_DIGEST, 0, outDigest, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +TSS_RESULT +RPC_PcrReset_TP(struct host_table_entry *hte, + UINT32 pcrDataSizeIn, /* in */ + BYTE * pcrDataIn) /* in */ +{ + TSS_RESULT result; + + initData(&hte->comm, 3); + hte->comm.hdr.u.ordinal = TCSD_ORD_PCRRESET; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &pcrDataSizeIn, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 2, pcrDataIn, pcrDataSizeIn, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_ps.c b/src/tspi/rpc/tcstp/rpc_ps.c new file mode 100644 index 0000000..3a4d704 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_ps.c @@ -0,0 +1,373 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_GetRegisteredKeyByPublicInfo_TP(struct host_table_entry *hte, + TCPA_ALGORITHM_ID algID, /* in */ + UINT32 ulPublicInfoLength, /* in */ + BYTE * rgbPublicInfo, /* in */ + UINT32 * keySize, /* out */ + BYTE ** keyBlob) /* out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 4); + hte->comm.hdr.u.ordinal = TCSD_ORD_GETREGISTEREDKEYBYPUBLICINFO; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &algID, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &ulPublicInfoLength, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 3, rgbPublicInfo, ulPublicInfoLength, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, keySize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + *keyBlob = (BYTE *) malloc(*keySize); + if (*keyBlob == NULL) { + LogError("malloc of %u bytes failed.", *keySize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *keyBlob, *keySize, &hte->comm)) { + free(*keyBlob); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + +done: + return result; +} + +TSS_RESULT +RPC_RegisterKey_TP(struct host_table_entry *hte, + TSS_UUID WrappingKeyUUID, /* in */ + TSS_UUID KeyUUID, /* in */ + UINT32 cKeySize, /* in */ + BYTE * rgbKey, /* in */ + UINT32 cVendorData, /* in */ + BYTE * gbVendorData /* in */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 7); + hte->comm.hdr.u.ordinal = TCSD_ORD_REGISTERKEY; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UUID, 1, &WrappingKeyUUID, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UUID, 2, &KeyUUID, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 3, &cKeySize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 4, rgbKey, cKeySize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 5, &cVendorData, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 6, gbVendorData, cVendorData, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + return result; +} + +TSS_RESULT +RPC_UnregisterKey_TP(struct host_table_entry *hte, + TSS_UUID KeyUUID /* in */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_UNREGISTERKEY; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UUID, 1, &KeyUUID, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + return result; +} + +TSS_RESULT +RPC_EnumRegisteredKeys_TP(struct host_table_entry *hte, + TSS_UUID * pKeyUUID, /* in */ + UINT32 * pcKeyHierarchySize, /* out */ + TSS_KM_KEYINFO ** ppKeyHierarchy /* out */ + ) { + TSS_RESULT result; + int i, j; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_ENUMREGISTEREDKEYS; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (pKeyUUID != NULL) { + if (setData(TCSD_PACKET_TYPE_UUID, 1, pKeyUUID, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (getData(TCSD_PACKET_TYPE_UINT32, i++, pcKeyHierarchySize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + if (*pcKeyHierarchySize > 0) { + *ppKeyHierarchy = malloc((*pcKeyHierarchySize) * sizeof(TSS_KM_KEYINFO)); + if (*ppKeyHierarchy == NULL) { + LogError("malloc of %zu bytes failed.", (*pcKeyHierarchySize) * + sizeof(TSS_KM_KEYINFO)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + for (j = 0; (UINT32)j < *pcKeyHierarchySize; j++) { + if (getData(TCSD_PACKET_TYPE_KM_KEYINFO, i++, + &((*ppKeyHierarchy)[j]), 0, &hte->comm)) { + free(*ppKeyHierarchy); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + } else { + *ppKeyHierarchy = NULL; + } + } + +done: + return result; +} + +TSS_RESULT +RPC_EnumRegisteredKeys2_TP(struct host_table_entry *hte, + TSS_UUID * pKeyUUID, /* in */ + UINT32 * pcKeyHierarchySize, /* out */ + TSS_KM_KEYINFO2 ** ppKeyHierarchy /* out */ + ) +{ + TSS_RESULT result; + int i, j; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_ENUMREGISTEREDKEYS2; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (pKeyUUID != NULL) { + if (setData(TCSD_PACKET_TYPE_UUID, 1, pKeyUUID, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (getData(TCSD_PACKET_TYPE_UINT32, i++, pcKeyHierarchySize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + if (*pcKeyHierarchySize > 0) { + *ppKeyHierarchy = malloc((*pcKeyHierarchySize) * sizeof(TSS_KM_KEYINFO2)); + if (*ppKeyHierarchy == NULL) { + LogError("malloc of %zu bytes failed.", (*pcKeyHierarchySize) * + sizeof(TSS_KM_KEYINFO2)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + for (j = 0; (UINT32)j < *pcKeyHierarchySize; j++) { + if (getData(TCSD_PACKET_TYPE_KM_KEYINFO2, i++, + &((*ppKeyHierarchy)[j]), 0, &hte->comm)) { + free(*ppKeyHierarchy); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + } else { + *ppKeyHierarchy = NULL; + } + } + +done: + return result; +} + +TSS_RESULT +RPC_GetRegisteredKey_TP(struct host_table_entry *hte, + TSS_UUID KeyUUID, /* in */ + TSS_KM_KEYINFO ** ppKeyInfo /* out */ + ) { + return TSPERR(TSS_E_NOTIMPL); +} + +TSS_RESULT +RPC_GetRegisteredKeyBlob_TP(struct host_table_entry *hte, + TSS_UUID KeyUUID, /* in */ + UINT32 * pcKeySize, /* out */ + BYTE ** prgbKey /* out */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_GETREGISTEREDKEYBLOB; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UUID, 1, &KeyUUID, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, pcKeySize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + *prgbKey = malloc(*pcKeySize); + if (*prgbKey == NULL) { + LogError("malloc of %u bytes failed.", *pcKeySize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *prgbKey, *pcKeySize, &hte->comm)) { + free(*prgbKey); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + +done: + return result; + +} + +TSS_RESULT +RPC_LoadKeyByUUID_TP(struct host_table_entry *hte, + TSS_UUID KeyUUID, /* in */ + TCS_LOADKEY_INFO * pLoadKeyInfo, /* in, out */ + TCS_KEY_HANDLE * phKeyTCSI /* out */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 3); + hte->comm.hdr.u.ordinal = TCSD_ORD_LOADKEYBYUUID; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UUID, 1, &KeyUUID, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (pLoadKeyInfo != NULL) { + if (setData(TCSD_PACKET_TYPE_LOADKEY_INFO, 2, pLoadKeyInfo, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, phKeyTCSI, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + + LogDebugFn("TCS key handle: 0x%x", *phKeyTCSI); + } else if (pLoadKeyInfo && (result == (TCS_E_KM_LOADFAILED | TSS_LAYER_TCS))) { + if (getData(TCSD_PACKET_TYPE_LOADKEY_INFO, 0, pLoadKeyInfo, 0, &hte->comm)) + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + + return result; +} + +void +LoadBlob_LOADKEY_INFO(UINT64 *offset, BYTE *blob, TCS_LOADKEY_INFO *info) +{ + Trspi_LoadBlob_UUID(offset, blob, info->keyUUID); + Trspi_LoadBlob_UUID(offset, blob, info->parentKeyUUID); + Trspi_LoadBlob(offset, TCPA_DIGEST_SIZE, blob, info->paramDigest.digest); + Trspi_LoadBlob_UINT32(offset, info->authData.AuthHandle, blob); + Trspi_LoadBlob(offset, TCPA_NONCE_SIZE, blob, (BYTE *)&info->authData.NonceOdd.nonce); + Trspi_LoadBlob(offset, TCPA_NONCE_SIZE, blob, (BYTE *)&info->authData.NonceEven.nonce); + Trspi_LoadBlob_BOOL(offset, info->authData.fContinueAuthSession, blob); + Trspi_LoadBlob(offset, TCPA_DIGEST_SIZE, blob, (BYTE *)&info->authData.HMAC); +} + +void +UnloadBlob_LOADKEY_INFO(UINT64 *offset, BYTE *blob, TCS_LOADKEY_INFO *info) +{ + Trspi_UnloadBlob_UUID(offset, blob, &info->keyUUID); + Trspi_UnloadBlob_UUID(offset, blob, &info->parentKeyUUID); + Trspi_UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, (BYTE *)&info->paramDigest.digest); + Trspi_UnloadBlob_UINT32(offset, &info->authData.AuthHandle, blob); + Trspi_UnloadBlob(offset, TCPA_NONCE_SIZE, blob, (BYTE *)&info->authData.NonceOdd.nonce); + Trspi_UnloadBlob(offset, TCPA_NONCE_SIZE, blob, (BYTE *)&info->authData.NonceEven.nonce); + Trspi_UnloadBlob_BOOL(offset, &info->authData.fContinueAuthSession, blob); + Trspi_UnloadBlob(offset, TCPA_DIGEST_SIZE, blob, (BYTE *)&info->authData.HMAC); +} + diff --git a/src/tspi/rpc/tcstp/rpc_quote.c b/src/tspi/rpc/tcstp/rpc_quote.c new file mode 100644 index 0000000..7bb1961 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_quote.c @@ -0,0 +1,114 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_Quote_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE keyHandle, /* in */ + TCPA_NONCE *antiReplay, /* in */ + UINT32 pcrDataSizeIn, /* in */ + BYTE * pcrDataIn, /* in */ + TPM_AUTH * privAuth, /* in, out */ + UINT32 * pcrDataSizeOut, /* out */ + BYTE ** pcrDataOut, /* out */ + UINT32 * sigSize, /* out */ + BYTE ** sig) /* out */ +{ + TSS_RESULT result; + int i; + + initData(&hte->comm, 6); + + hte->comm.hdr.u.ordinal = TCSD_ORD_QUOTE; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &keyHandle, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_NONCE, 2, antiReplay, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 3, &pcrDataSizeIn, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 4, pcrDataIn, pcrDataSizeIn, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (privAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 5, privAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (privAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, privAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, pcrDataSizeOut, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *pcrDataOut = (BYTE *) malloc(*pcrDataSizeOut); + if (*pcrDataOut == NULL) { + LogError("malloc of %u bytes failed.", *pcrDataSizeOut); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *pcrDataOut, *pcrDataSizeOut, &hte->comm)) { + free(*pcrDataOut); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, sigSize, 0, &hte->comm)) { + free(*pcrDataOut); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + *sig = (BYTE *) malloc(*sigSize); + if (*sig == NULL) { + LogError("malloc of %u bytes failed.", *sigSize); + free(*pcrDataOut); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *sig, *sigSize, &hte->comm)) { + free(*pcrDataOut); + free(*sig); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + +done: + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_quote2.c b/src/tspi/rpc/tcstp/rpc_quote2.c new file mode 100644 index 0000000..798748f --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_quote2.c @@ -0,0 +1,149 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_Quote2_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE keyHandle, /* in */ + TCPA_NONCE *antiReplay, /* in */ + UINT32 pcrDataSizeIn, /* in */ + BYTE * pcrDataIn, /* in */ + TSS_BOOL addVersion, /* in */ + TPM_AUTH * privAuth, /* in, out */ + UINT32 * pcrDataSizeOut, /* out */ + BYTE ** pcrDataOut, /* out */ + UINT32* versionInfoSize, /* out */ + BYTE** versionInfo, /* out */ + UINT32 * sigSize, /* out */ + BYTE ** sig) /* out */ +{ + TSS_RESULT result; + int i; + + initData(&hte->comm, 7); + + hte->comm.hdr.u.ordinal = TCSD_ORD_QUOTE2; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &keyHandle, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_NONCE, 2, antiReplay, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 3, &pcrDataSizeIn, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 4, pcrDataIn, pcrDataSizeIn, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_BOOL, 5, &addVersion, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (privAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 6, privAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + /* Takes and sets the output data */ + if (result == TSS_SUCCESS) { + i = 0; + if (privAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, privAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, pcrDataSizeOut, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *pcrDataOut = (BYTE *) malloc(*pcrDataSizeOut); + if (*pcrDataOut == NULL) { + LogError("malloc of %u bytes failed.", *pcrDataSizeOut); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *pcrDataOut, *pcrDataSizeOut, &hte->comm)) { + free(*pcrDataOut); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + /* Retrieves the versionInfo Parameters */ + if (getData(TCSD_PACKET_TYPE_UINT32, i++, versionInfoSize, 0, &hte->comm)) { + free(*pcrDataOut); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (*versionInfoSize >0){ + *versionInfo = (BYTE *) malloc(*versionInfoSize); + if (*versionInfo == NULL) { + LogError("malloc of %u bytes failed.", *versionInfoSize); + free(*pcrDataOut); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *versionInfo, *versionInfoSize, + &hte->comm)) { + free(*pcrDataOut); + free(*versionInfo); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + + if (getData(TCSD_PACKET_TYPE_UINT32, i++, sigSize, 0, &hte->comm)) { + free(*pcrDataOut); + if (addVersion) + free(*versionInfo); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + *sig = (BYTE *) malloc(*sigSize); + if (*sig == NULL) { + LogError("malloc of %u bytes failed.", *sigSize); + free(*pcrDataOut); + if (addVersion) + free(*versionInfo); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *sig, *sigSize, &hte->comm)) { + free(*pcrDataOut); + if (addVersion) + free(*versionInfo); + free(*sig); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + +done: + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_random.c b/src/tspi/rpc/tcstp/rpc_random.c new file mode 100644 index 0000000..82edd05 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_random.c @@ -0,0 +1,94 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_GetRandom_TP(struct host_table_entry *hte, + UINT32 bytesRequested, /* in */ + BYTE ** randomBytes) /* out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 2); + hte->comm.hdr.u.ordinal = TCSD_ORD_GETRANDOM; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &bytesRequested, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, &bytesRequested, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + *randomBytes = (BYTE *) malloc(bytesRequested); + if (*randomBytes == NULL) { + LogError("malloc of %u bytes failed.", bytesRequested); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *randomBytes, bytesRequested, &hte->comm)) { + free(*randomBytes); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + +done: + return result; +} + +TSS_RESULT +RPC_StirRandom_TP(struct host_table_entry *hte, + UINT32 inDataSize, /* in */ + BYTE * inData) /* in */ +{ + TSS_RESULT result; + + initData(&hte->comm, 3); + hte->comm.hdr.u.ordinal = TCSD_ORD_STIRRANDOM; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &inDataSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 2, inData, inDataSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_seal.c b/src/tspi/rpc/tcstp/rpc_seal.c new file mode 100644 index 0000000..2bca7e2 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_seal.c @@ -0,0 +1,206 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +common_Seal_TP(UINT32 sealOrdinal, + struct host_table_entry *hte, + TCS_KEY_HANDLE keyHandle, /* in */ + TCPA_ENCAUTH *encAuth, /* in */ + UINT32 pcrInfoSize, /* in */ + BYTE * PcrInfo, /* in */ + UINT32 inDataSize, /* in */ + BYTE * inData, /* in */ + TPM_AUTH * pubAuth, /* in, out */ + UINT32 * SealedDataSize, /* out */ + BYTE ** SealedData /* out */ + ) { + TSS_RESULT result; + int i = 0; + + initData(&hte->comm, 8); + hte->comm.hdr.u.ordinal = sealOrdinal; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, i++, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, i++, &keyHandle, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_ENCAUTH, i++, encAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, i++, &pcrInfoSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (pcrInfoSize > 0) { + if (setData(TCSD_PACKET_TYPE_PBYTE, i++, PcrInfo, pcrInfoSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (setData(TCSD_PACKET_TYPE_UINT32, i++, &inDataSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (inDataSize > 0) { + if (setData(TCSD_PACKET_TYPE_PBYTE, i++, inData, inDataSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + if (setData(TCSD_PACKET_TYPE_AUTH, i, pubAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (hte->comm.hdr.u.result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, pubAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + if (getData(TCSD_PACKET_TYPE_UINT32, 1, SealedDataSize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *SealedData = (BYTE *) malloc(*SealedDataSize); + if (*SealedData == NULL) { + LogError("malloc of %u bytes failed.", *SealedDataSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 2, *SealedData, *SealedDataSize, &hte->comm)) { + free(*SealedData); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + +done: + return result; +} + +TSS_RESULT +RPC_Seal_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE keyHandle, /* in */ + TCPA_ENCAUTH *encAuth, /* in */ + UINT32 pcrInfoSize, /* in */ + BYTE * PcrInfo, /* in */ + UINT32 inDataSize, /* in */ + BYTE * inData, /* in */ + TPM_AUTH * pubAuth, /* in, out */ + UINT32 * SealedDataSize, /* out */ + BYTE ** SealedData /* out */ + ) { + return common_Seal_TP(TCSD_ORD_SEAL, hte, keyHandle, encAuth, pcrInfoSize, PcrInfo, + inDataSize, inData, pubAuth, SealedDataSize, SealedData); +} + +#ifdef TSS_BUILD_SEALX +TSS_RESULT +RPC_Sealx_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE keyHandle, /* in */ + TCPA_ENCAUTH *encAuth, /* in */ + UINT32 pcrInfoSize, /* in */ + BYTE * PcrInfo, /* in */ + UINT32 inDataSize, /* in */ + BYTE * inData, /* in */ + TPM_AUTH * pubAuth, /* in, out */ + UINT32 * SealedDataSize, /* out */ + BYTE ** SealedData /* out */ + ) { + return common_Seal_TP(TCSD_ORD_SEALX, hte, keyHandle, encAuth, pcrInfoSize, PcrInfo, + inDataSize, inData, pubAuth, SealedDataSize, SealedData); +} +#endif + +TSS_RESULT +RPC_Unseal_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE parentHandle, /* in */ + UINT32 SealedDataSize, /* in */ + BYTE * SealedData, /* in */ + TPM_AUTH * parentAuth, /* in, out */ + TPM_AUTH * dataAuth, /* in, out */ + UINT32 * DataSize, /* out */ + BYTE ** Data /* out */ + ) { + TSS_RESULT result; + + initData(&hte->comm, 6); + hte->comm.hdr.u.ordinal = TCSD_ORD_UNSEAL; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &parentHandle, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &SealedDataSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 3, SealedData, SealedDataSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (parentAuth != NULL) { + if (setData(TCSD_PACKET_TYPE_AUTH, 4, parentAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + if (setData(TCSD_PACKET_TYPE_AUTH, 5, dataAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (parentAuth != NULL) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, parentAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + + if (getData(TCSD_PACKET_TYPE_AUTH, 1, dataAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + if (getData(TCSD_PACKET_TYPE_UINT32, 2, DataSize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *Data = (BYTE *) malloc(*DataSize); + if (*Data == NULL) { + LogError("malloc of %u bytes failed.", *DataSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 3, *Data, *DataSize, &hte->comm)) { + free(*Data); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + +done: + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_selftest.c b/src/tspi/rpc/tcstp/rpc_selftest.c new file mode 100644 index 0000000..3cad950 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_selftest.c @@ -0,0 +1,155 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_SelfTestFull_TP(struct host_table_entry *hte) +{ + TSS_RESULT result; + + initData(&hte->comm, 1); + hte->comm.hdr.u.ordinal = TCSD_ORD_SELFTESTFULL; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + return result; +} + +TSS_RESULT +RPC_CertifySelfTest_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE keyHandle, /* in */ + TCPA_NONCE antiReplay, /* in */ + TPM_AUTH * privAuth, /* in, out */ + UINT32 * sigSize, /* out */ + BYTE ** sig) /* out */ +{ + TSS_RESULT result; + int i; + + initData(&hte->comm, 4); + hte->comm.hdr.u.ordinal = TCSD_ORD_CERTIFYSELFTEST; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &keyHandle, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_NONCE, 2, &antiReplay, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (privAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 3, privAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (privAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, privAuth, 0, &hte->comm)) { + LogDebug("privAuth"); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, sigSize, 0, &hte->comm)) { + LogDebug("sigSize"); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + *sig = (BYTE *) malloc(*sigSize); + if (*sig == NULL) { + LogError("malloc of %u bytes failed.", *sigSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *sig, *sigSize, &hte->comm)) { + LogDebug("sig"); + free(*sig); + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + +done: + return result; +} + +TSS_RESULT +RPC_GetTestResult_TP(struct host_table_entry *hte, + UINT32 * outDataSize, /* out */ + BYTE ** outData) /* out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 1); + hte->comm.hdr.u.ordinal = TCSD_ORD_GETTESTRESULT; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + LogDebug("RPC_GetTestResult_TP"); + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + LogDebug("sendTCSDPacket succeeded"); + if (getData(TCSD_PACKET_TYPE_UINT32, 0, outDataSize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *outData = malloc(*outDataSize); + if (*outData == NULL) { + LogError("malloc of %u bytes failed.", *outDataSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *outData, *outDataSize, &hte->comm)) { + free(*outData); + *outData = NULL; + result = TSPERR(TSS_E_INTERNAL_ERROR); + } + } + LogDebug("RPC_GetTestResult_TP exit"); + +done: + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_sign.c b/src/tspi/rpc/tcstp/rpc_sign.c new file mode 100644 index 0000000..dcaf478 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_sign.c @@ -0,0 +1,93 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_Sign_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE keyHandle, /* in */ + UINT32 areaToSignSize, /* in */ + BYTE * areaToSign, /* in */ + TPM_AUTH * privAuth, /* in, out */ + UINT32 * sigSize, /* out */ + BYTE ** sig /* out */ + ) { + TSS_RESULT result; + int i; + + initData(&hte->comm, 5); + hte->comm.hdr.u.ordinal = TCSD_ORD_SIGN; + LogDebugFn("TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &keyHandle, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &areaToSignSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 3, areaToSign, areaToSignSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (privAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 4, privAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (privAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, privAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, sigSize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *sig = (BYTE *) malloc(*sigSize); + if (*sig == NULL) { + LogError("malloc of %u bytes failed.", *sigSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *sig, *sigSize, &hte->comm)) { + result = free_tspi(hte->tspContext, *sig); + if (result == TSS_SUCCESS) + result = TSPERR(TSS_E_INTERNAL_ERROR); + else + free(*sig); + } + } + +done: + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_tick.c b/src/tspi/rpc/tcstp/rpc_tick.c new file mode 100644 index 0000000..6ad0f34 --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_tick.c @@ -0,0 +1,172 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_ReadCurrentTicks_TP(struct host_table_entry* hte, + UINT32* pulCurrentTime, /* out */ + BYTE** prgbCurrentTime) /* out */ +{ + TSS_RESULT result; + + initData(&hte->comm, 1); + hte->comm.hdr.u.ordinal = TCSD_ORD_READCURRENTTICKS; + LogDebugFn("IN: TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (getData(TCSD_PACKET_TYPE_UINT32, 0, pulCurrentTime, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *prgbCurrentTime = malloc(*pulCurrentTime); + if (*prgbCurrentTime == NULL) { + *pulCurrentTime = 0; + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + if (getData(TCSD_PACKET_TYPE_PBYTE, 1, *prgbCurrentTime, *pulCurrentTime, + &hte->comm)) { + free(*prgbCurrentTime); + *prgbCurrentTime = NULL; + *pulCurrentTime = 0; + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } +done: + return result; +} + +TSS_RESULT +RPC_TickStampBlob_TP(struct host_table_entry* hte, + TCS_KEY_HANDLE hKey, /* in */ + TPM_NONCE* antiReplay, /* in */ + TPM_DIGEST* digestToStamp, /* in */ + TPM_AUTH* privAuth, /* in, out */ + UINT32* pulSignatureLength, /* out */ + BYTE** prgbSignature, /* out */ + UINT32* pulTickCountLength, /* out */ + BYTE** prgbTickCount) /* out */ + +{ + TSS_RESULT result; + UINT32 i; + + initData(&hte->comm, 5); + hte->comm.hdr.u.ordinal = TCSD_ORD_TICKSTAMPBLOB; + LogDebugFn("IN: TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hKey, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_NONCE, 2, antiReplay, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_DIGEST, 3, digestToStamp, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (privAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 4, privAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (privAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, privAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + + if (getData(TCSD_PACKET_TYPE_UINT32, i++, pulSignatureLength, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *prgbSignature = malloc(*pulSignatureLength); + if (*prgbSignature == NULL) { + *pulSignatureLength = 0; + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *prgbSignature, *pulSignatureLength, + &hte->comm)) { + free(*prgbSignature); + *prgbSignature = NULL; + *pulSignatureLength = 0; + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + if (getData(TCSD_PACKET_TYPE_UINT32, i++, pulTickCountLength, 0, &hte->comm)) { + free(*prgbSignature); + *prgbSignature = NULL; + *pulSignatureLength = 0; + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *prgbTickCount = malloc(*pulTickCountLength); + if (*prgbTickCount == NULL) { + free(*prgbSignature); + *prgbSignature = NULL; + *pulSignatureLength = 0; + *pulTickCountLength = 0; + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *prgbTickCount, *pulTickCountLength, + &hte->comm)) { + free(*prgbSignature); + *prgbSignature = NULL; + *pulSignatureLength = 0; + free(*prgbTickCount); + *prgbTickCount = NULL; + *pulTickCountLength = 0; + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } +done: + return result; +} diff --git a/src/tspi/rpc/tcstp/rpc_transport.c b/src/tspi/rpc/tcstp/rpc_transport.c new file mode 100644 index 0000000..91102cc --- /dev/null +++ b/src/tspi/rpc/tcstp/rpc_transport.c @@ -0,0 +1,368 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "obj.h" +#include "rpc_tcstp_tsp.h" + + +TSS_RESULT +RPC_EstablishTransport_TP(struct host_table_entry *hte, + UINT32 ulTransControlFlags, + TCS_KEY_HANDLE hEncKey, + UINT32 ulTransSessionInfoSize, + BYTE* rgbTransSessionInfo, + UINT32 ulSecretSize, + BYTE* rgbSecret, + TPM_AUTH* pEncKeyAuth, /* in, out */ + TPM_MODIFIER_INDICATOR* pbLocality, + TCS_HANDLE* hTransSession, + UINT32* ulCurrentTicksSize, + BYTE** prgbCurrentTicks, + TPM_NONCE* pTransNonce) +{ + TSS_RESULT result; + UINT32 i; + + initData(&hte->comm, 8); + hte->comm.hdr.u.ordinal = TCSD_ORD_ESTABLISHTRANSPORT; + LogDebugFn("IN: TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &ulTransControlFlags, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 2, &hEncKey, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 3, &ulTransSessionInfoSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 4, rgbTransSessionInfo, ulTransSessionInfoSize, + &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 5, &ulSecretSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, 6, rgbSecret, ulSecretSize, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (pEncKeyAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 7, pEncKeyAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (pEncKeyAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, pEncKeyAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, pbLocality, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, hTransSession, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, ulCurrentTicksSize, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + + *prgbCurrentTicks = malloc(*ulCurrentTicksSize); + if (*prgbCurrentTicks == NULL) { + *ulCurrentTicksSize = 0; + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *prgbCurrentTicks, *ulCurrentTicksSize, + &hte->comm)) { + free(*prgbCurrentTicks); + *prgbCurrentTicks = NULL; + *ulCurrentTicksSize = 0; + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + if (getData(TCSD_PACKET_TYPE_NONCE, i++, pTransNonce, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } + } +done: + return result; +} + + +TSS_RESULT +RPC_ExecuteTransport_TP(struct host_table_entry *hte, + TPM_COMMAND_CODE unWrappedCommandOrdinal, + UINT32 ulWrappedCmdParamInSize, + BYTE* rgbWrappedCmdParamIn, + UINT32* pulHandleListSize, /* in, out */ + TCS_HANDLE** rghHandles, /* in, out */ + TPM_AUTH* pWrappedCmdAuth1, /* in, out */ + TPM_AUTH* pWrappedCmdAuth2, /* in, out */ + TPM_AUTH* pTransAuth, /* in, out */ + UINT64* punCurrentTicks, + TPM_MODIFIER_INDICATOR* pbLocality, + TPM_RESULT* pulWrappedCmdReturnCode, + UINT32* ulWrappedCmdParamOutSize, + BYTE** rgbWrappedCmdParamOut) +{ + TSS_RESULT result; + TPM_AUTH null_auth; + UINT32 i = 0; + + memset(&null_auth, 0, sizeof(TPM_AUTH)); + + initData(&hte->comm, 9); + hte->comm.hdr.u.ordinal = TCSD_ORD_EXECUTETRANSPORT; + LogDebugFn("IN: TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, i++, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, i++, &unWrappedCommandOrdinal, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, i++, &ulWrappedCmdParamInSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_PBYTE, i++, rgbWrappedCmdParamIn, ulWrappedCmdParamInSize, + &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, i++, pulHandleListSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (*pulHandleListSize) { + if (setData(TCSD_PACKET_TYPE_PBYTE, i++, *rghHandles, + *pulHandleListSize * sizeof(UINT32), &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (pWrappedCmdAuth1) { + if (setData(TCSD_PACKET_TYPE_AUTH, i++, pWrappedCmdAuth1, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } else { + if (setData(TCSD_PACKET_TYPE_AUTH, i++, &null_auth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (pWrappedCmdAuth2) { + if (setData(TCSD_PACKET_TYPE_AUTH, i++, pWrappedCmdAuth2, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } else { + if (setData(TCSD_PACKET_TYPE_AUTH, i++, &null_auth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (setData(TCSD_PACKET_TYPE_AUTH, i++, pTransAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + i = 0; + if (getData(TCSD_PACKET_TYPE_UINT32, i++, pulHandleListSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if (*pulHandleListSize) { + *rghHandles = malloc(*pulHandleListSize * sizeof(UINT32)); + if (*rghHandles == NULL) { + *pulHandleListSize = 0; + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *rghHandles, + *pulHandleListSize * sizeof(UINT32), &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto error; + } + } + if (pWrappedCmdAuth1) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, pWrappedCmdAuth1, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto error; + } + } else { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, &null_auth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto error; + } + } + if (pWrappedCmdAuth2) { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, pWrappedCmdAuth2, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto error; + } + } else { + if (getData(TCSD_PACKET_TYPE_AUTH, i++, &null_auth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto error; + } + } + if (getData(TCSD_PACKET_TYPE_AUTH, i++, pTransAuth, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto error; + } + if (getData(TCSD_PACKET_TYPE_UINT64, i++, punCurrentTicks, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto error; + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, pbLocality, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto error; + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, pulWrappedCmdReturnCode, 0, &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto error; + } + if (getData(TCSD_PACKET_TYPE_UINT32, i++, ulWrappedCmdParamOutSize, 0, + &hte->comm)) { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto error; + } + if (*ulWrappedCmdParamOutSize) { + *rgbWrappedCmdParamOut = malloc(*ulWrappedCmdParamOutSize); + if (*rgbWrappedCmdParamOut == NULL) { + *ulWrappedCmdParamOutSize = 0; + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto error; + } + if (getData(TCSD_PACKET_TYPE_PBYTE, i++, *rgbWrappedCmdParamOut, + *ulWrappedCmdParamOutSize, &hte->comm)) { + free(*rgbWrappedCmdParamOut); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto error; + } + } else + *rgbWrappedCmdParamOut = NULL; + } + + return result; +error: + if (*pulHandleListSize) { + free(*rghHandles); + *rghHandles = NULL; + } + return result; +} + +TSS_RESULT +RPC_ReleaseTransportSigned_TP(struct host_table_entry *hte, + TCS_KEY_HANDLE hSignatureKey, + TPM_NONCE* AntiReplayNonce, + TPM_AUTH* pKeyAuth, /* in, out */ + TPM_AUTH* pTransAuth, /* in, out */ + TPM_MODIFIER_INDICATOR* pbLocality, + UINT32* pulCurrentTicksSize, + BYTE** prgbCurrentTicks, + UINT32* pulSignatureSize, + BYTE** prgbSignature) +{ + TSS_RESULT result; + TPM_AUTH null_auth; + + memset(&null_auth, 0, sizeof(TPM_AUTH)); + + initData(&hte->comm, 5); + hte->comm.hdr.u.ordinal = TCSD_ORD_RELEASETRANSPORTSIGNED; + LogDebugFn("IN: TCS Context: 0x%x", hte->tcsContext); + + if (setData(TCSD_PACKET_TYPE_UINT32, 0, &hte->tcsContext, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_UINT32, 1, &hSignatureKey, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (setData(TCSD_PACKET_TYPE_NONCE, 2, AntiReplayNonce, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (pKeyAuth) { + if (setData(TCSD_PACKET_TYPE_AUTH, 3, pKeyAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } else { + if (setData(TCSD_PACKET_TYPE_AUTH, 3, &null_auth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (setData(TCSD_PACKET_TYPE_AUTH, 4, pTransAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = sendTCSDPacket(hte); + + if (result == TSS_SUCCESS) + result = hte->comm.hdr.u.result; + + if (result == TSS_SUCCESS) { + if (pKeyAuth) { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, pKeyAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } else { + if (getData(TCSD_PACKET_TYPE_AUTH, 0, &null_auth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (getData(TCSD_PACKET_TYPE_AUTH, 1, pTransAuth, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (getData(TCSD_PACKET_TYPE_UINT32, 2, pbLocality, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + if (getData(TCSD_PACKET_TYPE_UINT32, 3, pulCurrentTicksSize, 0, &hte->comm)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + *prgbCurrentTicks = malloc(*pulCurrentTicksSize); + if (*prgbCurrentTicks == NULL) { + *pulCurrentTicksSize = 0; + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 4, *prgbCurrentTicks, *pulCurrentTicksSize, + &hte->comm)) { + free(*prgbCurrentTicks); + *prgbCurrentTicks = NULL; + *pulCurrentTicksSize = 0; + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (getData(TCSD_PACKET_TYPE_UINT32, 5, pulSignatureSize, 0, &hte->comm)) { + free(*prgbCurrentTicks); + *prgbCurrentTicks = NULL; + *pulCurrentTicksSize = 0; + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + *prgbSignature = malloc(*pulSignatureSize); + if (*prgbSignature == NULL) { + free(*prgbCurrentTicks); + *prgbCurrentTicks = NULL; + *pulCurrentTicksSize = 0; + *pulSignatureSize = 0; + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (getData(TCSD_PACKET_TYPE_PBYTE, 6, *prgbSignature, *pulSignatureSize, + &hte->comm)) { + free(*prgbCurrentTicks); + *prgbCurrentTicks = NULL; + *pulCurrentTicksSize = 0; + free(*prgbSignature); + *prgbSignature = NULL; + *pulSignatureSize = 0; + return TSPERR(TSS_E_INTERNAL_ERROR); + } + } + + return result; +} diff --git a/src/tspi/spi_utils.c b/src/tspi/spi_utils.c new file mode 100644 index 0000000..de80bc1 --- /dev/null +++ b/src/tspi/spi_utils.c @@ -0,0 +1,459 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <errno.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_UUID NULL_UUID = { 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0 } }; + +TSS_VERSION VERSION_1_1 = { 1, 1, 0, 0 }; + +struct tcs_api_table tcs_normal_api = { +#ifdef TSS_BUILD_KEY + .LoadKeyByBlob = RPC_LoadKeyByBlob, + .EvictKey = RPC_EvictKey, + .CreateWrapKey = RPC_CreateWrapKey, + .GetPubKey = RPC_GetPubKey, +#ifdef TSS_BUILD_TSS12 + .OwnerReadInternalPub = RPC_OwnerReadInternalPub, +#endif +#ifdef TSS_BUILD_CERTIFY + .CertifyKey = RPC_CertifyKey, +#endif +#endif +#ifdef TSS_BUILD_OWN + .OwnerClear = RPC_OwnerClear, + .ForceClear = RPC_ForceClear, +#endif +#ifdef TSS_BUILD_AUTH + .TerminateHandle = RPC_TerminateHandle, + .OIAP = RPC_OIAP, + .OSAP = RPC_OSAP, +#endif +#ifdef TSS_BUILD_CHANGEAUTH + .ChangeAuth = RPC_ChangeAuth, + .ChangeAuthOwner = RPC_ChangeAuthOwner, + .ChangeAuthAsymStart = RPC_ChangeAuthAsymStart, + .ChangeAuthAsymFinish = RPC_ChangeAuthAsymFinish, +#endif +#ifdef TSS_BUILD_AIK + .ActivateTPMIdentity = RPC_ActivateTPMIdentity, +#endif +#ifdef TSS_BUILD_PCR_EXTEND + .Extend = RPC_Extend, + .PcrRead = RPC_PcrRead, + .PcrReset = RPC_PcrReset, +#endif +#ifdef TSS_BUILD_QUOTE + .Quote = RPC_Quote, +#endif +#ifdef TSS_BUILD_QUOTE2 + .Quote2 = RPC_Quote2, +#endif +#ifdef TSS_BUILD_DIR + .DirWriteAuth = RPC_DirWriteAuth, + .DirRead = RPC_DirRead, +#endif +#ifdef TSS_BUILD_SEAL + .Seal = RPC_Seal, + .Unseal = RPC_Unseal, +#ifdef TSS_BUILD_SEALX + .Sealx = RPC_Sealx, +#endif +#endif +#ifdef TSS_BUILD_BIND + .UnBind = RPC_UnBind, +#endif +#ifdef TSS_BUILD_MIGRATION + .CreateMigrationBlob = RPC_CreateMigrationBlob, + .ConvertMigrationBlob = RPC_ConvertMigrationBlob, + .AuthorizeMigrationKey = RPC_AuthorizeMigrationKey, +#endif +#ifdef TSS_BUILD_SIGN + .Sign = RPC_Sign, +#endif +#ifdef TSS_BUILD_RANDOM + .GetRandom = RPC_GetRandom, + .StirRandom = RPC_StirRandom, +#endif +#ifdef TSS_BUILD_CAPS_TPM + .GetTPMCapability = RPC_GetTPMCapability, + .SetCapability = RPC_SetCapability, + .GetCapabilityOwner = RPC_GetCapabilityOwner, +#endif +#ifdef TSS_BUILD_EK + .CreateEndorsementKeyPair = RPC_CreateEndorsementKeyPair, + .ReadPubek = RPC_ReadPubek, + .OwnerReadPubek = RPC_OwnerReadPubek, +#endif +#ifdef TSS_BUILD_SELFTEST + .SelfTestFull = RPC_SelfTestFull, + .CertifySelfTest = RPC_CertifySelfTest, + .GetTestResult = RPC_GetTestResult, +#endif +#ifdef TSS_BUILD_ADMIN + .SetOwnerInstall = RPC_SetOwnerInstall, + .DisablePubekRead = RPC_DisablePubekRead, + .OwnerSetDisable = RPC_OwnerSetDisable, + .DisableOwnerClear = RPC_DisableOwnerClear, + .DisableForceClear = RPC_DisableForceClear, + .PhysicalDisable = RPC_PhysicalDisable, + .PhysicalEnable = RPC_PhysicalEnable, + .PhysicalSetDeactivated = RPC_PhysicalSetDeactivated, + .PhysicalPresence = RPC_PhysicalPresence, + .SetTempDeactivated = RPC_SetTempDeactivated, +#ifdef TSS_BUILD_TSS12 + .SetTempDeactivated2 = RPC_SetTempDeactivated2, + .ResetLockValue = RPC_ResetLockValue, +#endif +#endif +#ifdef TSS_BUILD_MAINT + .CreateMaintenanceArchive = RPC_CreateMaintenanceArchive, + .LoadMaintenanceArchive = RPC_LoadMaintenanceArchive, + .KillMaintenanceFeature = RPC_KillMaintenanceFeature, + .LoadManuMaintPub = RPC_LoadManuMaintPub, + .ReadManuMaintPub = RPC_ReadManuMaintPub, +#endif +#ifdef TSS_BUILD_DAA + .DaaJoin = RPC_DaaJoin, + .DaaSign = RPC_DaaSign, +#endif +#ifdef TSS_BUILD_COUNTER + .ReadCounter = RPC_ReadCounter, + .CreateCounter = RPC_CreateCounter, + .IncrementCounter = RPC_IncrementCounter, + .ReleaseCounter = RPC_ReleaseCounter, + .ReleaseCounterOwner = RPC_ReleaseCounterOwner, +#endif +#ifdef TSS_BUILD_TICK + .ReadCurrentTicks = RPC_ReadCurrentTicks, + .TickStampBlob = RPC_TickStampBlob, +#endif +#ifdef TSS_BUILD_NV + .NV_DefineOrReleaseSpace = RPC_NV_DefineOrReleaseSpace, + .NV_WriteValue = RPC_NV_WriteValue, + .NV_WriteValueAuth = RPC_NV_WriteValueAuth, + .NV_ReadValue = RPC_NV_ReadValue, + .NV_ReadValueAuth = RPC_NV_ReadValueAuth, +#endif +#ifdef TSS_BUILD_AUDIT + .SetOrdinalAuditStatus = RPC_SetOrdinalAuditStatus, + .GetAuditDigest = RPC_GetAuditDigest, + .GetAuditDigestSigned = RPC_GetAuditDigestSigned, +#endif +#ifdef TSS_BUILD_TSS12 + .SetOperatorAuth = RPC_SetOperatorAuth, + .FlushSpecific = RPC_FlushSpecific, +#endif +#ifdef TSS_BUILD_DELEGATION + .Delegate_Manage = RPC_Delegate_Manage, + .Delegate_CreateKeyDelegation = RPC_Delegate_CreateKeyDelegation, + .Delegate_CreateOwnerDelegation = RPC_Delegate_CreateOwnerDelegation, + .Delegate_LoadOwnerDelegation = RPC_Delegate_LoadOwnerDelegation, + .Delegate_ReadTable = RPC_Delegate_ReadTable, + .Delegate_UpdateVerificationCount = RPC_Delegate_UpdateVerificationCount, + .Delegate_VerifyDelegation = RPC_Delegate_VerifyDelegation, + .DSAP = RPC_DSAP, +#endif + .FieldUpgrade = RPC_FieldUpgrade, + .SetRedirection = RPC_SetRedirection, +}; + +#ifdef TSS_BUILD_TRANSPORT +struct tcs_api_table tcs_transport_api = { +#ifdef TSS_BUILD_KEY + .LoadKeyByBlob = Transport_LoadKeyByBlob, + .EvictKey = Transport_EvictKey, + .CreateWrapKey = Transport_CreateWrapKey, + .GetPubKey = Transport_GetPubKey, +#ifdef TSS_BUILD_TSS12 + .OwnerReadInternalPub = Transport_OwnerReadInternalPub, +#endif +#ifdef TSS_BUILD_CERTIFY + .CertifyKey = Transport_CertifyKey, +#endif +#endif +#ifdef TSS_BUILD_OWN + .OwnerClear = Transport_OwnerClear, + .ForceClear = Transport_ForceClear, +#endif +#ifdef TSS_BUILD_AUTH + .OIAP = Transport_OIAP, + .OSAP = Transport_OSAP, + .TerminateHandle = Transport_TerminateHandle, +#endif +#ifdef TSS_BUILD_CHANGEAUTH + .ChangeAuth = Transport_ChangeAuth, + .ChangeAuthOwner = Transport_ChangeAuthOwner, + .ChangeAuthAsymStart = RPC_ChangeAuthAsymStart, + .ChangeAuthAsymFinish = RPC_ChangeAuthAsymFinish, +#endif +#ifdef TSS_BUILD_AIK + .ActivateTPMIdentity = Transport_ActivateTPMIdentity, +#endif +#ifdef TSS_BUILD_PCR_EXTEND + .Extend = Transport_Extend, + .PcrRead = Transport_PcrRead, + .PcrReset = Transport_PcrReset, +#endif +#ifdef TSS_BUILD_QUOTE + .Quote = Transport_Quote, +#endif +#ifdef TSS_BUILD_QUOTE2 + .Quote2 = Transport_Quote2, +#endif +#ifdef TSS_BUILD_DIR + .DirWriteAuth = Transport_DirWriteAuth, + .DirRead = Transport_DirRead, +#endif +#ifdef TSS_BUILD_SEAL + .Seal = Transport_Seal, + .Sealx = Transport_Sealx, + .Unseal = Transport_Unseal, +#endif +#ifdef TSS_BUILD_BIND + .UnBind = Transport_UnBind, +#endif +#ifdef TSS_BUILD_MIGRATION + .CreateMigrationBlob = Transport_CreateMigrationBlob, + .ConvertMigrationBlob = Transport_ConvertMigrationBlob, + .AuthorizeMigrationKey = Transport_AuthorizeMigrationKey, +#endif +#ifdef TSS_BUILD_SIGN + .Sign = Transport_Sign, +#endif +#ifdef TSS_BUILD_RANDOM + .GetRandom = Transport_GetRandom, + .StirRandom = Transport_StirRandom, +#endif +#ifdef TSS_BUILD_CAPS_TPM + .GetTPMCapability = Transport_GetTPMCapability, + .SetCapability = Transport_SetCapability, + .GetCapabilityOwner = Transport_GetCapabilityOwner, +#endif +#ifdef TSS_BUILD_EK + .ReadPubek = RPC_ReadPubek, + .OwnerReadPubek = RPC_OwnerReadPubek, +#endif +#ifdef TSS_BUILD_SELFTEST + .SelfTestFull = Transport_SelfTestFull, + .CertifySelfTest = Transport_CertifySelfTest, + .GetTestResult = Transport_GetTestResult, +#endif +#ifdef TSS_BUILD_ADMIN + .SetOwnerInstall = Transport_SetOwnerInstall, + .DisablePubekRead = Transport_DisablePubekRead, + .OwnerSetDisable = Transport_OwnerSetDisable, + .ResetLockValue = Transport_ResetLockValue, + .DisableOwnerClear = Transport_DisableOwnerClear, + .DisableForceClear = Transport_DisableForceClear, + .PhysicalDisable = Transport_PhysicalDisable, + .PhysicalEnable = Transport_PhysicalEnable, + .PhysicalSetDeactivated = Transport_PhysicalSetDeactivated, + .PhysicalPresence = Transport_PhysicalPresence, + .SetTempDeactivated = Transport_SetTempDeactivated, + .SetTempDeactivated2 = Transport_SetTempDeactivated2, +#endif +#ifdef TSS_BUILD_MAINT + .CreateMaintenanceArchive = Transport_CreateMaintenanceArchive, + .LoadMaintenanceArchive = Transport_LoadMaintenanceArchive, + .KillMaintenanceFeature = Transport_KillMaintenanceFeature, + .LoadManuMaintPub = Transport_LoadManuMaintPub, + .ReadManuMaintPub = Transport_ReadManuMaintPub, +#endif +#ifdef TSS_BUILD_DAA + .DaaJoin = RPC_DaaJoin, + .DaaSign = RPC_DaaSign, +#endif +#ifdef TSS_BUILD_COUNTER + .ReadCounter = Transport_ReadCounter, + .CreateCounter = RPC_CreateCounter, + .IncrementCounter = RPC_IncrementCounter, + .ReleaseCounter = RPC_ReleaseCounter, + .ReleaseCounterOwner = RPC_ReleaseCounterOwner, +#endif +#ifdef TSS_BUILD_TICK + .ReadCurrentTicks = Transport_ReadCurrentTicks, + .TickStampBlob = Transport_TickStampBlob, +#endif +#ifdef TSS_BUILD_NV + .NV_DefineOrReleaseSpace = Transport_NV_DefineOrReleaseSpace, + .NV_WriteValue = Transport_NV_WriteValue, + .NV_WriteValueAuth = Transport_NV_WriteValueAuth, + .NV_ReadValue = Transport_NV_ReadValue, + .NV_ReadValueAuth = Transport_NV_ReadValueAuth, +#endif +#ifdef TSS_BUILD_AUDIT + .SetOrdinalAuditStatus = Transport_SetOrdinalAuditStatus, + .GetAuditDigest = Transport_GetAuditDigest, + .GetAuditDigestSigned = Transport_GetAuditDigestSigned, +#endif +#ifdef TSS_BUILD_TSS12 + .SetOperatorAuth = Transport_SetOperatorAuth, + .FlushSpecific = Transport_FlushSpecific, +#endif +#ifdef TSS_BUILD_DELEGATION + .Delegate_Manage = Transport_Delegate_Manage, + .Delegate_CreateKeyDelegation = Transport_Delegate_CreateKeyDelegation, + .Delegate_CreateOwnerDelegation = Transport_Delegate_CreateOwnerDelegation, + .Delegate_LoadOwnerDelegation = Transport_Delegate_LoadOwnerDelegation, + .Delegate_ReadTable = Transport_Delegate_ReadTable, + .Delegate_UpdateVerificationCount = Transport_Delegate_UpdateVerificationCount, + .Delegate_VerifyDelegation = Transport_Delegate_VerifyDelegation, + .DSAP = Transport_DSAP, +#endif + .FieldUpgrade = RPC_FieldUpgrade, + .SetRedirection = RPC_SetRedirection, +}; +#endif + +UINT16 +Decode_UINT16(BYTE * in) +{ + UINT16 temp = 0; + temp = (in[1] & 0xFF); + temp |= (in[0] << 8); + return temp; +} + +void +UINT32ToArray(UINT32 i, BYTE * out) +{ + out[0] = (BYTE) ((i >> 24) & 0xFF); + out[1] = (BYTE) ((i >> 16) & 0xFF); + out[2] = (BYTE) ((i >> 8) & 0xFF); + out[3] = (BYTE) i & 0xFF; +} + +void +UINT64ToArray(UINT64 i, BYTE *out) +{ + out[0] = (BYTE) ((i >> 56) & 0xFF); + out[1] = (BYTE) ((i >> 48) & 0xFF); + out[2] = (BYTE) ((i >> 40) & 0xFF); + out[3] = (BYTE) ((i >> 32) & 0xFF); + out[4] = (BYTE) ((i >> 24) & 0xFF); + out[5] = (BYTE) ((i >> 16) & 0xFF); + out[6] = (BYTE) ((i >> 8) & 0xFF); + out[7] = (BYTE) i & 0xFF; +} + +void +UINT16ToArray(UINT16 i, BYTE * out) +{ + out[0] = ((i >> 8) & 0xFF); + out[1] = i & 0xFF; +} + +UINT64 +Decode_UINT64(BYTE *y) +{ + UINT64 x = 0; + + x = y[0]; + x = ((x << 8) | (y[1] & 0xFF)); + x = ((x << 8) | (y[2] & 0xFF)); + x = ((x << 8) | (y[3] & 0xFF)); + x = ((x << 8) | (y[4] & 0xFF)); + x = ((x << 8) | (y[5] & 0xFF)); + x = ((x << 8) | (y[6] & 0xFF)); + x = ((x << 8) | (y[7] & 0xFF)); + + return x; +} + +UINT32 +Decode_UINT32(BYTE * y) +{ + UINT32 x = 0; + + x = y[0]; + x = ((x << 8) | (y[1] & 0xFF)); + x = ((x << 8) | (y[2] & 0xFF)); + x = ((x << 8) | (y[3] & 0xFF)); + + return x; +} + +UINT32 +get_pcr_event_size(TSS_PCR_EVENT *e) +{ + return (sizeof(TSS_PCR_EVENT) + e->ulEventLength + e->ulPcrValueLength); +} + +void +LoadBlob_AUTH(UINT64 *offset, BYTE *blob, TPM_AUTH *auth) +{ + Trspi_LoadBlob_UINT32(offset, auth->AuthHandle, blob); + Trspi_LoadBlob(offset, 20, blob, auth->NonceOdd.nonce); + Trspi_LoadBlob_BOOL(offset, auth->fContinueAuthSession, blob); + Trspi_LoadBlob(offset, 20, blob, (BYTE *)&auth->HMAC); +} + +void +UnloadBlob_AUTH(UINT64 *offset, BYTE *blob, TPM_AUTH *auth) +{ + Trspi_UnloadBlob(offset, 20, blob, auth->NonceEven.nonce); + Trspi_UnloadBlob_BOOL(offset, &auth->fContinueAuthSession, blob); + Trspi_UnloadBlob(offset, 20, blob, (BYTE *)&auth->HMAC); +} + +/* If alloc is true, we allocate a new buffer for the bytes and set *data to that. + * If alloc is false, data is really a BYTE*, so write the bytes directly to that buffer */ +TSS_RESULT +get_local_random(TSS_HCONTEXT tspContext, TSS_BOOL alloc, UINT32 size, BYTE **data) +{ + FILE *f = NULL; + BYTE *buf = NULL; + + f = fopen(TSS_LOCAL_RANDOM_DEVICE, "r"); + if (f == NULL) { + LogError("open of %s failed: %s", TSS_LOCAL_RANDOM_DEVICE, strerror(errno)); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + if (alloc) { + buf = calloc_tspi(tspContext, size); + if (buf == NULL) { + LogError("malloc of %u bytes failed", size); + fclose(f); + return TSPERR(TSS_E_OUTOFMEMORY); + } + } else + buf = (BYTE *)data; + + if (fread(buf, size, 1, f) == 0) { + LogError("fread of %s failed: %s", TSS_LOCAL_RANDOM_DEVICE, strerror(errno)); + fclose(f); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + if (alloc) + *data = buf; + fclose(f); + + return TSS_SUCCESS; +} diff --git a/src/tspi/ssl_ui.c b/src/tspi/ssl_ui.c new file mode 100644 index 0000000..5e25895 --- /dev/null +++ b/src/tspi/ssl_ui.c @@ -0,0 +1,86 @@ + +#include <sys/types.h> +#include <string.h> + +#include <openssl/ui.h> + +#include "trousers/tss.h" +#include "spi_utils.h" + +static TSS_RESULT do_ui(BYTE *string, UINT32 *string_len, BYTE *popup, int verify) +{ + char pin_buf[UI_MAX_SECRET_STRING_LENGTH + 1]; + char verify_buf[UI_MAX_SECRET_STRING_LENGTH + 1]; + char *popup_nl; + UI *ui; + BYTE *unicode; + TSS_RESULT ret = TSS_E_FAIL; + + popup_nl = malloc(strlen((char *)popup) + 2); + if (!popup_nl) + return TSS_E_OUTOFMEMORY; + + ui = UI_new(); + if (!ui) + goto no_ui; + + sprintf(popup_nl, "%s\n", (char *)popup); + if (!UI_add_info_string(ui, popup_nl)) { + printf("add info fail\n"); + goto out; + } + + /* UI_add_input_string() doesn't count for the null terminator in its last */ + /* parameter, that's why we statically allocated 1 more byte to pin_buf */ + if (!UI_add_input_string(ui, "Enter PIN:", 0, pin_buf, 1, UI_MAX_SECRET_STRING_LENGTH)) { + printf("add input fail\n"); + goto out; + } + + if (verify && + !UI_add_verify_string(ui, "Verify PIN:", 0, verify_buf, 1, UI_MAX_SECRET_STRING_LENGTH, pin_buf)) { + printf("Add verify fail\n"); + goto out; + } + + if (UI_process(ui)) + goto out; + + ret = TSS_SUCCESS; + + unicode = Trspi_Native_To_UNICODE((BYTE *)pin_buf, string_len); + memset(string, 0, UI_MAX_SECRET_STRING_LENGTH); + memcpy(string, unicode, *string_len); + out: + UI_free(ui); + no_ui: + free(popup_nl); + return ret; +} + +/* + * DisplayPINWindow() + * + * Popup the dialog to collect an existing password. + * + * string - buffer that the password will be passed back to caller in + * popup - UTF-8 string to be displayed in the title bar of the dialog box + * + */ +TSS_RESULT DisplayPINWindow(BYTE *string, UINT32 *string_len, BYTE *popup) +{ + return do_ui(string, string_len, popup, 0); +} +/* + * DisplayNewPINWindow() + * + * Popup the dialog to collect a new password. + * + * string - buffer that the password will be passed back to caller in + * popup - UTF-8 string to be displayed in the title bar of the dialog box + * + */ +TSS_RESULT DisplayNewPINWindow(BYTE *string, UINT32 *string_len, BYTE *popup) +{ + return do_ui(string, string_len, popup, 1); +} diff --git a/src/tspi/tsp_admin.c b/src/tspi/tsp_admin.c new file mode 100644 index 0000000..8b856c6 --- /dev/null +++ b/src/tspi/tsp_admin.c @@ -0,0 +1,305 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + + +#include <stdlib.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_GetCapabilityOwner(TSS_HCONTEXT tspContext, /* in */ + TPM_AUTH * pOwnerAuth, /* in/out */ + TCPA_VERSION * pVersion, /* out */ + UINT32 * pNonVolatileFlags, /* out */ + UINT32 * pVolatileFlags) /* out */ +{ + UINT64 offset; + TSS_RESULT result; + UINT32 handlesLen = 0, decLen; + BYTE *dec; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetCapabilityOwner, 0, NULL, + NULL, &handlesLen, NULL, pOwnerAuth, NULL, + &decLen, &dec))) + return result; + + offset = 0; + Trspi_UnloadBlob_TCPA_VERSION(&offset, dec, pVersion); + Trspi_UnloadBlob_UINT32(&offset, pNonVolatileFlags, dec); + Trspi_UnloadBlob_UINT32(&offset, pVolatileFlags, dec); + + free(dec); + + return result; +} + +TSS_RESULT +Transport_SetOwnerInstall(TSS_HCONTEXT tspContext, /* in */ + TSS_BOOL state) /* in */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + result = obj_context_transport_execute(tspContext, TPM_ORD_SetOwnerInstall, + sizeof(TSS_BOOL), (BYTE *)&state, NULL, &handlesLen, + NULL, NULL, NULL, NULL, NULL); + + return result; +} + +TSS_RESULT +Transport_DisableOwnerClear(TSS_HCONTEXT tspContext, /* in */ + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + result = obj_context_transport_execute(tspContext, TPM_ORD_DisableOwnerClear, 0, NULL, NULL, + &handlesLen, NULL, ownerAuth, NULL, NULL, NULL); + + return result; +} + +TSS_RESULT +Transport_DisableForceClear(TSS_HCONTEXT tspContext) /* in */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + result = obj_context_transport_execute(tspContext, TPM_ORD_DisableForceClear, 0, NULL, NULL, + &handlesLen, NULL, NULL, NULL, NULL, NULL); + + return result; +} + +TSS_RESULT +Transport_OwnerSetDisable(TSS_HCONTEXT tspContext, /* in */ + TSS_BOOL disableState, /* in */ + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + result = obj_context_transport_execute(tspContext, TPM_ORD_OwnerSetDisable, + sizeof(TSS_BOOL), (BYTE *)&disableState, NULL, + &handlesLen, NULL, ownerAuth, NULL, NULL, NULL); + + return result; +} + +TSS_RESULT +Transport_PhysicalDisable(TSS_HCONTEXT tspContext) /* in */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + result = obj_context_transport_execute(tspContext, TPM_ORD_PhysicalDisable, 0, NULL, NULL, + &handlesLen, NULL, NULL, NULL, NULL, NULL); + + return result; +} + +TSS_RESULT +Transport_PhysicalEnable(TSS_HCONTEXT tspContext) /* in */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + result = obj_context_transport_execute(tspContext, TPM_ORD_PhysicalEnable, 0, NULL, NULL, + &handlesLen, NULL, NULL, NULL, NULL, NULL); + + return result; +} + +TSS_RESULT +Transport_PhysicalSetDeactivated(TSS_HCONTEXT tspContext, /* in */ + TSS_BOOL state) /* in */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + result = obj_context_transport_execute(tspContext, TPM_ORD_PhysicalSetDeactivated, + sizeof(TSS_BOOL), (BYTE *)&state, NULL, &handlesLen, + NULL, NULL, NULL, NULL, NULL); + + return result; +} + +TSS_RESULT +Transport_SetTempDeactivated(TSS_HCONTEXT tspContext) /* in */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + result = obj_context_transport_execute(tspContext, TPM_ORD_SetTempDeactivated, 0, NULL, + NULL, &handlesLen, NULL, NULL, NULL, NULL, NULL); + + return result; +} + +TSS_RESULT +Transport_SetTempDeactivated2(TSS_HCONTEXT tspContext, /* in */ + TPM_AUTH *operatorAuth) /* in, out */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + result = obj_context_transport_execute(tspContext, TPM_ORD_SetTempDeactivated, 0, NULL, + NULL, &handlesLen, NULL, operatorAuth, NULL, NULL, + NULL); + + return result; +} + +TSS_RESULT +Transport_DisablePubekRead(TSS_HCONTEXT tspContext, /* in */ + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + result = obj_context_transport_execute(tspContext, TPM_ORD_DisablePubekRead, 0, NULL, NULL, + &handlesLen, NULL, ownerAuth, NULL, NULL, NULL); + + return result; +} + +TSS_RESULT +Transport_ResetLockValue(TSS_HCONTEXT tspContext, /* in */ + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + result = obj_context_transport_execute(tspContext, TPM_ORD_ResetLockValue, 0, NULL, NULL, + &handlesLen, NULL, ownerAuth, NULL, NULL, NULL); + + return result; +} + +TSS_RESULT +Transport_PhysicalPresence(TSS_HCONTEXT tspContext, /* in */ + TCPA_PHYSICAL_PRESENCE fPhysicalPresence) /* in */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + result = obj_context_transport_execute(tspContext, TSC_ORD_PhysicalPresence, + sizeof(TCPA_PHYSICAL_PRESENCE), + (BYTE *)&fPhysicalPresence, NULL, &handlesLen, NULL, + NULL, NULL, NULL, NULL); + + return result; +} + +TSS_RESULT +Transport_FlushSpecific(TSS_HCONTEXT tspContext, /* in */ + TCS_HANDLE hResHandle, /* in */ + TPM_RESOURCE_TYPE resourceType) /* in */ +{ + UINT64 offset; + TSS_RESULT result; + UINT32 handlesLen = 1; + TCS_HANDLE *handles, handle; + BYTE data[sizeof(UINT32)]; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + handle = hResHandle; + handles = &handle; + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, resourceType, data); + + result = obj_context_transport_execute(tspContext, TPM_ORD_FlushSpecific, sizeof(data), + data, NULL, &handlesLen, &handles, NULL, NULL, NULL, + NULL); + + return result; +} +#endif + diff --git a/src/tspi/tsp_aik.c b/src/tspi/tsp_aik.c new file mode 100644 index 0000000..ead4134 --- /dev/null +++ b/src/tspi/tsp_aik.c @@ -0,0 +1,143 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + + +#include <stdlib.h> +#include <string.h> +#include <limits.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_ActivateTPMIdentity(TSS_HCONTEXT tspContext, + TCS_KEY_HANDLE idKey, /* in */ + UINT32 blobSize, /* in */ + BYTE * blob, /* in */ + TPM_AUTH * idKeyAuth, /* in, out */ + TPM_AUTH * ownerAuth, /* in, out */ + UINT32 * SymmetricKeySize, /* out */ + BYTE ** SymmetricKey) /* out */ +{ + TSS_RESULT result; + UINT32 handlesLen, decLen; + TCS_HANDLE *handles, handle; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + BYTE *dec; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(idKey, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + handlesLen = 1; + handle = idKey; + handles = &handle; + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_ActivateIdentity, blobSize, + blob, &pubKeyHash, &handlesLen, &handles, + idKeyAuth, ownerAuth, &decLen, &dec))) + return result; + + *SymmetricKeySize = decLen; + *SymmetricKey = dec; + + return result; +} + +TSS_RESULT +Transport_MakeIdentity2(TSS_HCONTEXT tspContext, + TCPA_ENCAUTH identityAuth, /* in */ + TCPA_CHOSENID_HASH IDLabel_PrivCAHash, /* in */ + UINT32 idKeyInfoSize, /* in */ + BYTE * idKeyInfo, /* in */ + TPM_AUTH * pSrkAuth, /* in, out */ + TPM_AUTH * pOwnerAuth, /* in, out */ + UINT32 * idKeySize, /* out */ + BYTE ** idKey, /* out */ + UINT32 * pcIdentityBindingSize, /* out */ + BYTE ** prgbIdentityBinding) /* out */ +{ + UINT64 offset; + TSS_RESULT result; + UINT32 handlesLen = 0, decLen, dataLen; + BYTE *dec, *data; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + dataLen = sizeof(TCPA_ENCAUTH) + sizeof(TCPA_CHOSENID_HASH) + idKeyInfoSize; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob(&offset, sizeof(TCPA_ENCAUTH), data, identityAuth.authdata); + Trspi_LoadBlob(&offset, sizeof(TCPA_CHOSENID_HASH), data, IDLabel_PrivCAHash.digest); + Trspi_LoadBlob(&offset, idKeyInfoSize, data, idKeyInfo); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_MakeIdentity, dataLen, + data, NULL, &handlesLen, NULL, pSrkAuth, + pOwnerAuth, &decLen, &dec))) { + free(data); + return result; + } + free(data); + + offset = 0; + UnloadBlob_TSS_KEY(&offset, dec, NULL); + *idKeySize = offset; + + if ((*idKey = malloc(*idKeySize)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *idKeySize); + *idKeySize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_UnloadBlob(&offset, *idKeySize, dec, *idKey); + + Trspi_UnloadBlob_UINT32(&offset, pcIdentityBindingSize, dec); + if ((*prgbIdentityBinding = malloc(*pcIdentityBindingSize)) == NULL) { + free(dec); + free(*idKey); + *idKey = NULL; + *idKeySize = 0; + LogError("malloc of %u bytes failed", *pcIdentityBindingSize); + *pcIdentityBindingSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *pcIdentityBindingSize, dec, *prgbIdentityBinding); + free(dec); + + return result; +} +#endif + diff --git a/src/tspi/tsp_asym.c b/src/tspi/tsp_asym.c new file mode 100644 index 0000000..721e8fd --- /dev/null +++ b/src/tspi/tsp_asym.c @@ -0,0 +1,117 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +/* encrypt some data with the RSA public key of 'key', using the padding appropriate for the key */ +TSS_RESULT +__tspi_rsa_encrypt(TSS_HKEY key, + UINT32 inDataLen, + BYTE* inData, + UINT32* outDataLen, + BYTE* outData) +{ + BYTE *blob; + UINT32 blobLen; + UINT64 offset; + TSS_RESULT result; + TSS_HCONTEXT tspContext; + TPM_PUBKEY pubKey; + + if (!inData || !outDataLen || !outData) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if ((result = obj_rsakey_get_tsp_context(key, &tspContext))) + return result; + + if ((result = obj_rsakey_get_pub_blob(key, &blobLen, &blob))) + return result; + + offset = 0; + if ((result = Trspi_UnloadBlob_PUBKEY(&offset, blob, &pubKey))) { + free_tspi(tspContext, blob); + return result; + } + free_tspi(tspContext, blob); + + if (pubKey.pubKey.keyLength < inDataLen) { + result = TSPERR(TSS_E_ENC_INVALID_LENGTH); + goto done; + } + + if (pubKey.algorithmParms.encScheme == TPM_ES_RSAESPKCSv15 || + pubKey.algorithmParms.encScheme == TSS_ES_RSAESPKCSV15) { + if ((result = Trspi_RSA_PKCS15_Encrypt(inData, inDataLen, outData, outDataLen, + pubKey.pubKey.key, pubKey.pubKey.keyLength))) + goto done; + } else { + if ((result = Trspi_TPM_RSA_OAEP_Encrypt(inData, inDataLen, outData, outDataLen, + pubKey.pubKey.key, + pubKey.pubKey.keyLength))) + goto done; + } + +done: + free(pubKey.pubKey.key); + free(pubKey.algorithmParms.parms); + return result; +} + +TSS_RESULT +__tspi_rsa_verify(TSS_HKEY key, + UINT32 type, + UINT32 hashLen, + BYTE* hash, + UINT32 sigLen, + BYTE* sig) +{ + BYTE *blob; + UINT32 blobLen; + UINT64 offset; + TSS_RESULT result; + TSS_HCONTEXT tspContext; + TPM_PUBKEY pubKey; + + if (!hash || !sig) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if ((result = obj_rsakey_get_tsp_context(key, &tspContext))) + return result; + + if ((result = obj_rsakey_get_pub_blob(key, &blobLen, &blob))) + return result; + + offset = 0; + if ((result = Trspi_UnloadBlob_PUBKEY(&offset, blob, &pubKey))) { + free_tspi(tspContext, blob); + return result; + } + free_tspi(tspContext, blob); + + result = Trspi_Verify(type, hash, hashLen, pubKey.pubKey.key, pubKey.pubKey.keyLength, + sig, sigLen); + + free(pubKey.pubKey.key); + free(pubKey.algorithmParms.parms); + + return result; +} diff --git a/src/tspi/tsp_audit.c b/src/tspi/tsp_audit.c new file mode 100644 index 0000000..1c5faf1 --- /dev/null +++ b/src/tspi/tsp_audit.c @@ -0,0 +1,256 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +__tspi_audit_set_ordinal_audit_status(TSS_HTPM hTpm, + TSS_FLAG flag, + TSS_FLAG subFlag, + UINT32 ulOrdinal) +{ + TSS_BOOL bAuditState; + TSS_HCONTEXT tspContext; + TSS_HPOLICY hPolicy; + TPM_AUTH ownerAuth; + Trspi_HashCtx hashCtx; + TCPA_DIGEST digest; + TSS_RESULT result = TSS_SUCCESS; + + if (flag != TSS_TSPATTRIB_TPM_ORDINAL_AUDIT_STATUS) + return TSPERR(TSS_E_BAD_PARAMETER); + + switch (subFlag) { + case TPM_CAP_PROP_TPM_SET_ORDINAL_AUDIT: + bAuditState = TRUE; + break; + + case TPM_CAP_PROP_TPM_CLEAR_ORDINAL_AUDIT: + bAuditState = FALSE; + break; + + default: + return TSPERR(TSS_E_BAD_PARAMETER); + } + + if ((result = obj_tpm_get_tsp_context(hTpm, &tspContext))) + return result; + + if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_SetOrdinalAuditStatus); + result |= Trspi_Hash_UINT32(&hashCtx, ulOrdinal); + result |= Trspi_Hash_BOOL(&hashCtx, bAuditState); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_SetOrdinalAuditStatus, + hPolicy, FALSE, &digest, &ownerAuth))) + return result; + + if ((result = TCS_API(tspContext)->SetOrdinalAuditStatus(tspContext, &ownerAuth, ulOrdinal, + bAuditState))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_SetOrdinalAuditStatus); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + return obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth); +} + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_SetOrdinalAuditStatus(TSS_HCONTEXT tspContext, /* in */ + TPM_AUTH *ownerAuth, /* in/out */ + UINT32 ulOrdinal, /* in */ + TSS_BOOL bAuditState) /* in */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0; + UINT64 offset; + BYTE data[sizeof(UINT32) + sizeof(TSS_BOOL)]; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, ulOrdinal, data); + Trspi_LoadBlob_BOOL(&offset, bAuditState, data); + + result = obj_context_transport_execute(tspContext, TPM_ORD_SetOrdinalAuditStatus, + sizeof(data), data, NULL, &handlesLen, NULL, + ownerAuth, NULL, NULL, NULL); + return result; +} + +TSS_RESULT +Transport_GetAuditDigest(TSS_HCONTEXT tspContext, /* in */ + UINT32 startOrdinal, /* in */ + TPM_DIGEST *auditDigest, /* out */ + UINT32 *counterValueSize, /* out */ + BYTE **counterValue, /* out */ + TSS_BOOL *more, /* out */ + UINT32 *ordSize, /* out */ + UINT32 **ordList) /* out */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0, decLen; + BYTE *dec = NULL; + UINT64 offset; + BYTE data[sizeof(UINT32)]; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, startOrdinal, data); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetAuditDigest, + sizeof(data), data, NULL, &handlesLen, NULL, + NULL, NULL, &decLen, &dec))) + return result; + + offset = 0; + Trspi_UnloadBlob_COUNTER_VALUE(&offset, dec, NULL); + + *counterValueSize = (UINT32)offset; + if ((*counterValue = malloc(*counterValueSize)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *counterValueSize); + *counterValueSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + offset = 0; + Trspi_UnloadBlob(&offset, *counterValueSize, dec, *counterValue); + + Trspi_UnloadBlob_DIGEST(&offset, dec, auditDigest); + Trspi_UnloadBlob_BOOL(&offset, more, dec); + + Trspi_UnloadBlob_UINT32(&offset, ordSize, dec); + + if ((*ordList = malloc(*ordSize)) == NULL) { + free(dec); + free(*counterValue); + *counterValue = NULL; + *counterValueSize = 0; + LogError("malloc of %u bytes failed", *ordSize); + *ordSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + + Trspi_UnloadBlob(&offset, *ordSize, dec, *(BYTE **)ordList); + *ordSize /= sizeof(UINT32); + + return TSS_SUCCESS; +} + +TSS_RESULT +Transport_GetAuditDigestSigned(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + TSS_BOOL closeAudit, /* in */ + TPM_NONCE *antiReplay, /* in */ + TPM_AUTH *privAuth, /* in/out */ + UINT32 *counterValueSize, /* out */ + BYTE **counterValue, /* out */ + TPM_DIGEST *auditDigest, /* out */ + TPM_DIGEST *ordinalDigest, /* out */ + UINT32 *sigSize, /* out */ + BYTE **sig) /* out */ +{ + TSS_RESULT result; + UINT32 handlesLen, decLen; + TCS_HANDLE *handles, handle; + BYTE *dec = NULL; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + UINT64 offset; + BYTE data[sizeof(TSS_BOOL) + sizeof(TPM_NONCE)]; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + handlesLen = 1; + handle = keyHandle; + handles = &handle; + + offset = 0; + Trspi_LoadBlob_BOOL(&offset, closeAudit, data); + Trspi_LoadBlob_NONCE(&offset, data, antiReplay); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetAuditDigestSigned, + sizeof(data), data, &pubKeyHash, &handlesLen, + &handles, privAuth, NULL, &decLen, &dec))) + return result; + + offset = 0; + Trspi_UnloadBlob_COUNTER_VALUE(&offset, dec, NULL); + + *counterValueSize = (UINT32)offset; + if ((*counterValue = malloc(*counterValueSize)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *counterValueSize); + *counterValueSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + offset = 0; + Trspi_UnloadBlob(&offset, *counterValueSize, dec, *counterValue); + + Trspi_UnloadBlob_DIGEST(&offset, dec, auditDigest); + Trspi_UnloadBlob_DIGEST(&offset, dec, ordinalDigest); + + Trspi_UnloadBlob_UINT32(&offset, sigSize, dec); + + if ((*sig = malloc(*sigSize)) == NULL) { + free(dec); + free(*counterValue); + *counterValue = NULL; + *counterValueSize = 0; + LogError("malloc of %u bytes failed", *sigSize); + *counterValueSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *sigSize, dec, *sig); + + return TSS_SUCCESS; +} +#endif diff --git a/src/tspi/tsp_auth.c b/src/tspi/tsp_auth.c new file mode 100755 index 0000000..4a57ae7 --- /dev/null +++ b/src/tspi/tsp_auth.c @@ -0,0 +1,1230 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <errno.h> +#include <assert.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "tcs_tsp.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" +#include "authsess.h" + + +TSS_RESULT +secret_PerformAuth_OIAP(TSS_HOBJECT hAuthorizedObject, + UINT32 ulPendingFn, + TSS_HPOLICY hPolicy, + TSS_BOOL cas, /* continue auth session */ + TCPA_DIGEST *hashDigest, + TPM_AUTH *auth) +{ + TSS_RESULT result; + TSS_BOOL bExpired; + UINT32 mode; + TCPA_SECRET secret; + TSS_HCONTEXT tspContext; + TSS_RESULT (*OIAP)(TSS_HCONTEXT, TCS_AUTHHANDLE *, TPM_NONCE *); // XXX hack + TSS_RESULT (*TerminateHandle)(TSS_HCONTEXT, TCS_HANDLE); // XXX hack + + /* This validates that the secret can be used */ + if ((result = obj_policy_has_expired(hPolicy, &bExpired))) + return result; + + if (bExpired == TRUE) + return TSPERR(TSS_E_INVALID_OBJ_ACCESS); + + if ((result = obj_policy_get_tsp_context(hPolicy, &tspContext))) + return result; + + if ((result = obj_policy_get_mode(hPolicy, &mode))) + return result; + + if ((result = Init_AuthNonce(tspContext, cas, auth))) + return result; + + /* XXX hack for opening a transport session */ + if (cas) { + OIAP = RPC_OIAP; + TerminateHandle = RPC_TerminateHandle; + } else { + OIAP = TCS_API(tspContext)->OIAP; + TerminateHandle = TCS_API(tspContext)->TerminateHandle; + } + + /* added retry logic */ + if ((result = OIAP(tspContext, &auth->AuthHandle, &auth->NonceEven))) { + if (result == TCPA_E_RESOURCES) { + int retry = 0; + do { + /* POSIX sleep time, { secs, nanosecs } */ + struct timespec t = { 0, AUTH_RETRY_NANOSECS }; + + nanosleep(&t, NULL); + + result = OIAP(tspContext, &auth->AuthHandle, &auth->NonceEven); + } while (result == TCPA_E_RESOURCES && ++retry < AUTH_RETRY_COUNT); + } + + if (result) + return result; + } + + switch (mode) { + case TSS_SECRET_MODE_CALLBACK: + result = obj_policy_do_hmac(hPolicy, hAuthorizedObject, + TRUE, ulPendingFn, + auth->fContinueAuthSession, + 20, + auth->NonceEven.nonce, + auth->NonceOdd.nonce, + NULL, NULL, 20, + hashDigest->digest, + (BYTE *)&auth->HMAC); + break; + case TSS_SECRET_MODE_SHA1: + case TSS_SECRET_MODE_PLAIN: + case TSS_SECRET_MODE_POPUP: + if ((result = obj_policy_get_secret(hPolicy, TR_SECRET_CTX_NOT_NEW, + &secret))) + break; + + HMAC_Auth(secret.authdata, hashDigest->digest, auth); + break; + case TSS_SECRET_MODE_NONE: + /* fall through */ + default: + result = TSPERR(TSS_E_POLICY_NO_SECRET); + break; + } + + if (result) { + TerminateHandle(tspContext, auth->AuthHandle); + return result; + } + + return obj_policy_dec_counter(hPolicy); +} +#if 0 +TSS_RESULT +secret_PerformXOR_OSAP(TSS_HPOLICY hPolicy, TSS_HPOLICY hUsagePolicy, + TSS_HPOLICY hMigrationPolicy, TSS_HOBJECT hOSAPObject, + UINT16 osapType, UINT32 osapData, + TCPA_ENCAUTH * encAuthUsage, TCPA_ENCAUTH * encAuthMig, + BYTE *sharedSecret, TPM_AUTH * auth, TCPA_NONCE * nonceEvenOSAP) +{ + TSS_BOOL bExpired; + TCPA_SECRET keySecret; + TCPA_SECRET usageSecret; + TCPA_SECRET migSecret = { { 0, } }; + UINT32 keyMode, usageMode, migMode = 0; + TSS_RESULT result; + TSS_HCONTEXT tspContext; + + + if ((result = obj_policy_has_expired(hPolicy, &bExpired))) + return result; + + if (bExpired == TRUE) + return TSPERR(TSS_E_INVALID_OBJ_ACCESS); + + if ((result = obj_policy_has_expired(hUsagePolicy, &bExpired))) + return result; + + if (bExpired == TRUE) + return TSPERR(TSS_E_INVALID_OBJ_ACCESS); + + if (hMigrationPolicy) { + if ((result = obj_policy_has_expired(hMigrationPolicy, &bExpired))) + return result; + + if (bExpired == TRUE) + return TSPERR(TSS_E_INVALID_OBJ_ACCESS); + + if ((result = obj_policy_get_mode(hMigrationPolicy, &migMode))) + return result; + } + + if ((result = obj_policy_get_tsp_context(hPolicy, &tspContext))) + return result; + + if ((result = obj_policy_get_mode(hPolicy, &keyMode))) + return result; + + if ((result = obj_policy_get_mode(hUsagePolicy, &usageMode))) + return result; + + if (keyMode == TSS_SECRET_MODE_CALLBACK || + usageMode == TSS_SECRET_MODE_CALLBACK || + (hMigrationPolicy && migMode == TSS_SECRET_MODE_CALLBACK)) { + if (keyMode != TSS_SECRET_MODE_CALLBACK || + usageMode != TSS_SECRET_MODE_CALLBACK || + (hMigrationPolicy && migMode != TSS_SECRET_MODE_CALLBACK)) + return TSPERR(TSS_E_BAD_PARAMETER); + } + + if (keyMode != TSS_SECRET_MODE_CALLBACK) { + if ((result = obj_policy_get_secret(hPolicy, TR_SECRET_CTX_NOT_NEW, &keySecret))) + return result; + + if ((result = obj_policy_get_secret(hUsagePolicy, TR_SECRET_CTX_NEW, &usageSecret))) + return result; + + if (hMigrationPolicy) { + if ((result = obj_policy_get_secret(hMigrationPolicy, TR_SECRET_CTX_NEW, + &migSecret))) + return result; + } + + if ((result = OSAP_Calc(tspContext, osapType, osapData, + keySecret.authdata, usageSecret.authdata, + migSecret.authdata, encAuthUsage, + encAuthMig, sharedSecret, auth))) + return result; + } else { + /* If the secret mode is NONE here, we don't return an error. This is + * because there are commands such as CreateKey, which require an auth + * session even when creating no-auth keys. A secret of all 0's will be + * used in this case. */ + if ((result = TCS_API(tspContext)->OSAP(tspContext, osapType, osapData, + &auth->NonceOdd, &auth->AuthHandle, + &auth->NonceEven, nonceEvenOSAP))) + return result; + + if ((result = obj_policy_do_xor(hPolicy, hOSAPObject, + hPolicy, TRUE, 20, + auth->NonceEven.nonce, NULL, + nonceEvenOSAP->nonce, + auth->NonceOdd.nonce, 20, + encAuthUsage->authdata, + encAuthMig->authdata))) { + TCS_API(tspContext)->TerminateHandle(tspContext, auth->AuthHandle); + return result; + } + } + + return TSS_SUCCESS; +} + +TSS_RESULT +secret_PerformAuth_OSAP(TSS_HOBJECT hAuthorizedObject, UINT32 ulPendingFn, + TSS_HPOLICY hPolicy, TSS_HPOLICY hUsagePolicy, + TSS_HPOLICY hMigPolicy, BYTE sharedSecret[20], + TPM_AUTH *auth, BYTE *hashDigest, + TCPA_NONCE *nonceEvenOSAP) +{ + TSS_RESULT result; + UINT32 keyMode, usageMode, migMode = 0; + + if ((result = obj_policy_get_mode(hPolicy, &keyMode))) + return result; + + if ((result = obj_policy_get_mode(hUsagePolicy, &usageMode))) + return result; + + if (hMigPolicy) { + if ((result = obj_policy_get_mode(hMigPolicy, &migMode))) + return result; + } + + /* --- If any of them is a callback */ + if (keyMode == TSS_SECRET_MODE_CALLBACK || + usageMode == TSS_SECRET_MODE_CALLBACK || + (hMigPolicy && migMode == TSS_SECRET_MODE_CALLBACK)) { + /* --- And they're not all callback */ + if (keyMode != TSS_SECRET_MODE_CALLBACK || + usageMode != TSS_SECRET_MODE_CALLBACK || + (hMigPolicy && migMode != TSS_SECRET_MODE_CALLBACK)) + return TSPERR(TSS_E_BAD_PARAMETER); + } + + if (keyMode == TSS_SECRET_MODE_CALLBACK) { + if ((result = obj_policy_do_hmac(hPolicy, hAuthorizedObject, + TRUE, ulPendingFn, + auth->fContinueAuthSession, + 20, + auth->NonceEven.nonce, + NULL, + nonceEvenOSAP->nonce, + auth->NonceOdd.nonce, 20, + hashDigest, + (BYTE *)&auth->HMAC))) + return result; + } else { + HMAC_Auth(sharedSecret, hashDigest, auth); + } + + if ((result = obj_policy_dec_counter(hPolicy))) + return result; + + if ((result = obj_policy_dec_counter(hUsagePolicy))) + return result; + + if (hMigPolicy) { + if ((result = obj_policy_dec_counter(hMigPolicy))) + return result; + } + + return TSS_SUCCESS; +} + +TSS_RESULT +secret_ValidateAuth_OSAP(TSS_HOBJECT hAuthorizedObject, UINT32 ulPendingFn, + TSS_HPOLICY hPolicy, TSS_HPOLICY hUsagePolicy, + TSS_HPOLICY hMigPolicy, BYTE sharedSecret[20], + TPM_AUTH *auth, BYTE *hashDigest, + TCPA_NONCE *nonceEvenOSAP) +{ + TSS_RESULT result; + UINT32 keyMode, usageMode, migMode = 0; + + if ((result = obj_policy_get_mode(hPolicy, &keyMode))) + return result; + + if ((result = obj_policy_get_mode(hUsagePolicy, &usageMode))) + return result; + + if (hMigPolicy) { + if ((result = obj_policy_get_mode(hMigPolicy, &migMode))) + return result; + } + + /* --- If any of them is a callback */ + if (keyMode == TSS_SECRET_MODE_CALLBACK || + usageMode == TSS_SECRET_MODE_CALLBACK || + (hMigPolicy && migMode == TSS_SECRET_MODE_CALLBACK)) { + /* --- And they're not all callback */ + if (keyMode != TSS_SECRET_MODE_CALLBACK || + usageMode != TSS_SECRET_MODE_CALLBACK || + (hMigPolicy && migMode != TSS_SECRET_MODE_CALLBACK)) + return TSPERR(TSS_E_BAD_PARAMETER); + } + + if (keyMode != TSS_SECRET_MODE_CALLBACK) { + if (validateReturnAuth(sharedSecret, hashDigest, auth)) + return TSPERR(TSS_E_TSP_AUTHFAIL); + } else { + if ((result = obj_policy_do_hmac(hPolicy, hAuthorizedObject, + FALSE, ulPendingFn, + auth->fContinueAuthSession, + 20, + auth->NonceEven.nonce, + NULL, + nonceEvenOSAP->nonce, + auth->NonceOdd.nonce, 20, + hashDigest, + (BYTE *)&auth->HMAC))) + return result; + } + + return TSS_SUCCESS; +} +#endif +TSS_RESULT +Init_AuthNonce(TSS_HCONTEXT tspContext, TSS_BOOL cas, TPM_AUTH * auth) +{ + TSS_RESULT result; + + auth->fContinueAuthSession = cas; + if ((result = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE), + (BYTE **)auth->NonceOdd.nonce))) { + LogError("Failed creating random nonce"); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + return TSS_SUCCESS; +} + +TSS_BOOL +validateReturnAuth(BYTE *secret, BYTE *hash, TPM_AUTH *auth) +{ + BYTE digest[20]; + /* auth is expected to have both nonces and the digest from the TPM */ + memcpy(digest, &auth->HMAC, 20); + HMAC_Auth(secret, hash, auth); + + return ((TSS_BOOL) memcmp(digest, &auth->HMAC, 20) != 0); +} + +void +HMAC_Auth(BYTE * secret, BYTE * Digest, TPM_AUTH * auth) +{ + UINT64 offset; + BYTE Blob[61]; + + offset = 0; + Trspi_LoadBlob(&offset, 20, Blob, Digest); + Trspi_LoadBlob(&offset, 20, Blob, auth->NonceEven.nonce); + Trspi_LoadBlob(&offset, 20, Blob, auth->NonceOdd.nonce); + Blob[offset++] = auth->fContinueAuthSession; + + Trspi_HMAC(TSS_HASH_SHA1, 20, secret, offset, Blob, (BYTE *)&auth->HMAC); +} + +TSS_RESULT +OSAP_Calc(TSS_HCONTEXT tspContext, UINT16 EntityType, UINT32 EntityValue, + BYTE * authSecret, BYTE * usageSecret, BYTE * migSecret, + TCPA_ENCAUTH * encAuthUsage, TCPA_ENCAUTH * encAuthMig, + BYTE * sharedSecret, TPM_AUTH * auth) +{ + TSS_RESULT rc; + TCPA_NONCE nonceEvenOSAP; + UINT64 offset; + BYTE hmacBlob[0x200]; + BYTE hashBlob[0x200]; + BYTE xorUsageAuth[20]; + BYTE xorMigAuth[20]; + UINT32 i; + + if ((rc = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE), + (BYTE **)auth->NonceOdd.nonce))) { + LogError("Failed creating random nonce"); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + auth->fContinueAuthSession = 0x00; + + if ((rc = TCS_API(tspContext)->OSAP(tspContext, EntityType, EntityValue, &auth->NonceOdd, + &auth->AuthHandle, &auth->NonceEven, &nonceEvenOSAP))) { + if (rc == TCPA_E_RESOURCES) { + int retry = 0; + do { + /* POSIX sleep time, { secs, nanosecs } */ + struct timespec t = { 0, AUTH_RETRY_NANOSECS }; + + nanosleep(&t, NULL); + + rc = TCS_API(tspContext)->OSAP(tspContext, EntityType, EntityValue, + &auth->NonceOdd, &auth->AuthHandle, + &auth->NonceEven, &nonceEvenOSAP); + } while (rc == TCPA_E_RESOURCES && ++retry < AUTH_RETRY_COUNT); + } + + if (rc) + return rc; + } + + offset = 0; + Trspi_LoadBlob(&offset, 20, hmacBlob, nonceEvenOSAP.nonce); + Trspi_LoadBlob(&offset, 20, hmacBlob, auth->NonceOdd.nonce); + + Trspi_HMAC(TSS_HASH_SHA1, 20, authSecret, offset, hmacBlob, sharedSecret); + + offset = 0; + Trspi_LoadBlob(&offset, 20, hashBlob, sharedSecret); + Trspi_LoadBlob(&offset, 20, hashBlob, auth->NonceEven.nonce); + + if ((rc = Trspi_Hash(TSS_HASH_SHA1, offset, hashBlob, xorUsageAuth))) + return rc; + + offset = 0; + Trspi_LoadBlob(&offset, 20, hashBlob, sharedSecret); + Trspi_LoadBlob(&offset, 20, hashBlob, auth->NonceOdd.nonce); + if ((rc = Trspi_Hash(TSS_HASH_SHA1, offset, hashBlob, xorMigAuth))) + return rc; + + for (i = 0; i < sizeof(TCPA_ENCAUTH); i++) + encAuthUsage->authdata[i] = usageSecret[i] ^ xorUsageAuth[i]; + for (i = 0; i < sizeof(TCPA_ENCAUTH); i++) + encAuthMig->authdata[i] = migSecret[i] ^ xorMigAuth[i]; + + return TSS_SUCCESS; +} + +TSS_RESULT +obj_policy_validate_auth_oiap(TSS_HPOLICY hPolicy, TCPA_DIGEST *hashDigest, TPM_AUTH *auth) +{ + TSS_RESULT result = TSS_SUCCESS; + struct tsp_object *obj; + struct tr_policy_obj *policy; + BYTE wellKnown[TCPA_SHA1_160_HASH_LEN] = TSS_WELL_KNOWN_SECRET; + + if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL) + return TSPERR(TSS_E_INVALID_HANDLE); + + policy = (struct tr_policy_obj *)obj->data; + + switch (policy->SecretMode) { + case TSS_SECRET_MODE_CALLBACK: + result = policy->Tspicb_CallbackHMACAuth( + policy->hmacAppData, + hPolicy, + 0, + auth->fContinueAuthSession, + FALSE, + 20, + auth->NonceEven.nonce, + auth->NonceOdd.nonce, + NULL, NULL, 20, + hashDigest->digest, + (BYTE *)&auth->HMAC); + break; + case TSS_SECRET_MODE_SHA1: + case TSS_SECRET_MODE_PLAIN: + case TSS_SECRET_MODE_POPUP: + if (validateReturnAuth(policy->Secret, hashDigest->digest, auth)) + result = TSPERR(TSS_E_TSP_AUTHFAIL); + break; + case TSS_SECRET_MODE_NONE: + if (validateReturnAuth(wellKnown, hashDigest->digest, auth)) + result = TSPERR(TSS_E_TSP_AUTHFAIL); + break; + default: + result = TSPERR(TSS_E_POLICY_NO_SECRET); + break; + } + + obj_list_put(&policy_list); + + return result; +} + +#if 0 +TSS_RESULT +authsess_oiap_get(TSS_HOBJECT obj, TPM_COMMAND_CODE ord, TPM_DIGEST *digest, TPM_AUTH *auth) +{ + TSS_RESULT result = TSS_SUCCESS; + TSS_BOOL bExpired; + UINT32 mode; + TPM_SECRET secret; + TSS_HCONTEXT tspContext; + TSS_RESULT (*OIAP)(TSS_HCONTEXT, TCS_AUTHHANDLE *, TPM_NONCE *); // XXX hack + TSS_RESULT (*TerminateHandle)(TSS_HCONTEXT, TCS_HANDLE); // XXX hack + + + if (obj_is_tpm(obj)) + result = obj_tpm_get_tsp_context(obj, hContext); + else if (obj_is_rsakey(obj)) + result = obj_rsakey_get_tsp_context(obj, hContext); + else if (obj_is_encdata(obj)) + result = obj_encdata_get_tsp_context(obj, hContext); + else if (obj_is_nvstore(obj)) + result = obj_nvstore_get_tsp_context(obj, hContext); + else + result = TSPERR(TSS_E_INVALID_HANDLE); + +#if 0 + /* This validates that the secret can be used */ + if ((result = obj_policy_has_expired(hPolicy, &bExpired))) + return result; + + if (bExpired == TRUE) + return TSPERR(TSS_E_INVALID_OBJ_ACCESS); + + if ((result = obj_policy_get_tsp_context(hPolicy, &tspContext))) + return result; + + if ((result = obj_policy_get_mode(hPolicy, &mode))) + return result; +#else + if ((result = obj_policy_get_authsess_params())) + return result; +#endif + if ((result = Init_AuthNonce(tspContext, cas, auth))) + return result; + + /* XXX hack for opening a transport session */ + if (cas) { + OIAP = RPC_OIAP; + TerminateHandle = RPC_TerminateHandle; + } else { + OIAP = TCS_API(tspContext)->OIAP; + TerminateHandle = TCS_API(tspContext)->TerminateHandle; + } + + /* added retry logic */ + if ((result = OIAP(tspContext, &auth->AuthHandle, &auth->NonceEven))) { + if (result == TCPA_E_RESOURCES) { + int retry = 0; + do { + /* POSIX sleep time, { secs, nanosecs } */ + struct timespec t = { 0, AUTH_RETRY_NANOSECS }; + + nanosleep(&t, NULL); + + result = OIAP(tspContext, &auth->AuthHandle, &auth->NonceEven); + } while (result == TCPA_E_RESOURCES && ++retry < AUTH_RETRY_COUNT); + } + + if (result) + return result; + } + + switch (mode) { + case TSS_SECRET_MODE_CALLBACK: + result = obj_policy_do_hmac(hPolicy, hAuthorizedObject, + TRUE, ulPendingFn, + auth->fContinueAuthSession, + 20, + auth->NonceEven.nonce, + auth->NonceOdd.nonce, + NULL, NULL, 20, + hashDigest->digest, + (BYTE *)&auth->HMAC); + break; + case TSS_SECRET_MODE_SHA1: + case TSS_SECRET_MODE_PLAIN: + case TSS_SECRET_MODE_POPUP: + if ((result = obj_policy_get_secret(hPolicy, TR_SECRET_CTX_NOT_NEW, + &secret))) + break; + + HMAC_Auth(secret.authdata, hashDigest->digest, auth); + break; + case TSS_SECRET_MODE_NONE: + /* fall through */ + default: + result = TSPERR(TSS_E_POLICY_NO_SECRET); + break; + } + + if (result) { + TerminateHandle(tspContext, auth->AuthHandle); + return result; + } + + return obj_policy_dec_counter(hPolicy); +} + +TSS_RESULT +authsess_oiap_put(TPM_AUTH *auth) +{ +} +#endif + +#ifdef TSS_BUILD_DELEGATION +TSS_RESULT +authsess_do_dsap(struct authsess *sess) +{ + TSS_RESULT result; + + if ((result = TCS_API(sess->tspContext)->DSAP(sess->tspContext, sess->entity_type, + sess->obj_parent, &sess->nonceOddxSAP, + sess->entityValueSize, sess->entityValue, + &sess->pAuth->AuthHandle, + &sess->pAuth->NonceEven, + &sess->nonceEvenxSAP))) { + if (result == TCPA_E_RESOURCES) { + int retry = 0; + do { + /* POSIX sleep time, { secs, nanosecs } */ + struct timespec t = { 0, AUTH_RETRY_NANOSECS }; + + nanosleep(&t, NULL); + + result = TCS_API(sess->tspContext)->DSAP(sess->tspContext, + sess->entity_type, + sess->obj_parent, + &sess->nonceOddxSAP, + sess->entityValueSize, + sess->entityValue, + &sess->pAuth->AuthHandle, + &sess->pAuth->NonceEven, + &sess->nonceEvenxSAP); + } while (result == TCPA_E_RESOURCES && ++retry < AUTH_RETRY_COUNT); + } + } + + return result; +} +#endif + +TSS_RESULT +authsess_do_osap(struct authsess *sess) +{ + TSS_RESULT result; + + if ((result = TCS_API(sess->tspContext)->OSAP(sess->tspContext, sess->entity_type, + sess->obj_parent, &sess->nonceOddxSAP, + &sess->pAuth->AuthHandle, + &sess->pAuth->NonceEven, + &sess->nonceEvenxSAP))) { + if (result == TCPA_E_RESOURCES) { + int retry = 0; + do { + /* POSIX sleep time, { secs, nanosecs } */ + struct timespec t = { 0, AUTH_RETRY_NANOSECS }; + + nanosleep(&t, NULL); + + result = TCS_API(sess->tspContext)->OSAP(sess->tspContext, + sess->entity_type, + sess->obj_parent, + &sess->nonceOddxSAP, + &sess->pAuth->AuthHandle, + &sess->pAuth->NonceEven, + &sess->nonceEvenxSAP); + } while (result == TCPA_E_RESOURCES && ++retry < AUTH_RETRY_COUNT); + } + } + + return result; +} + +TSS_RESULT +authsess_callback_xor(PVOID lpAppData, + TSS_HOBJECT hOSAPObject, + TSS_HOBJECT hObject, + TSS_FLAG PurposeSecret, + UINT32 ulSizeNonces, + BYTE *rgbNonceEven, + BYTE *rgbNonceOdd, + BYTE *rgbNonceEvenOSAP, + BYTE *rgbNonceOddOSAP, + UINT32 ulSizeEncAuth, + BYTE *rgbEncAuthUsage, + BYTE *rgbEncAuthMigration) +{ + TSS_RESULT result; + BYTE xorUseAuth[sizeof(TPM_DIGEST)]; + BYTE xorMigAuth[sizeof(TPM_DIGEST)]; + Trspi_HashCtx hashCtx; + UINT32 i; + struct authsess *sess = (struct authsess *)lpAppData; + + /* sess->sharedSecret was calculated in authsess_xsap_init */ + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_SECRET(&hashCtx, sess->sharedSecret.digest); + result |= Trspi_Hash_NONCE(&hashCtx, rgbNonceEven); + if ((result |= Trspi_HashFinal(&hashCtx, xorUseAuth))) + return result; + + for (i = 0; i < ulSizeEncAuth; i++) + rgbEncAuthUsage[i] ^= xorUseAuth[i]; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_SECRET(&hashCtx, sess->sharedSecret.digest); + result |= Trspi_Hash_NONCE(&hashCtx, rgbNonceOdd); + if ((result |= Trspi_HashFinal(&hashCtx, xorMigAuth))) + return result; + + for (i = 0; i < ulSizeEncAuth; i++) + rgbEncAuthMigration[i] ^= xorMigAuth[i]; + + return TSS_SUCCESS; +} + +TSS_RESULT +authsess_callback_hmac(PVOID lpAppData, + TSS_HOBJECT hAuthorizedObject, + TSS_BOOL ReturnOrVerify, + UINT32 ulPendingFunction, + TSS_BOOL ContinueUse, + UINT32 ulSizeNonces, + BYTE *rgbNonceEven, + BYTE *rgbNonceOdd, + BYTE *rgbNonceEvenOSAP, + BYTE *rgbNonceOddOSAP, + UINT32 ulSizeDigestHmac, + BYTE *rgbParamDigest, + BYTE *rgbHmacData) +{ + struct authsess *sess = (struct authsess *)lpAppData; + TSS_RESULT result = TSS_SUCCESS; + UINT64 offset; + BYTE Blob[61]; + + offset = 0; + Trspi_LoadBlob(&offset, ulSizeDigestHmac, Blob, rgbParamDigest); + Trspi_LoadBlob(&offset, ulSizeNonces, Blob, rgbNonceEven); + Trspi_LoadBlob(&offset, ulSizeNonces, Blob, rgbNonceOdd); + Blob[offset++] = ContinueUse; + + if (ReturnOrVerify) { + Trspi_HMAC(TSS_HASH_SHA1, ulSizeDigestHmac, sess->sharedSecret.digest, offset, Blob, + rgbHmacData); + } else { + TPM_HMAC hmacVerify; + + Trspi_HMAC(TSS_HASH_SHA1, ulSizeDigestHmac, sess->sharedSecret.digest, offset, Blob, + hmacVerify.digest); + result = memcmp(rgbHmacData, hmacVerify.digest, ulSizeDigestHmac); + if (result) + result = TPM_E_AUTHFAIL; + } + + return result; +} + +/* Create an OSAP session. @requirements is used in different ways depending on the command to + * indicate whether we should require a policy or auth value */ +TSS_RESULT +authsess_xsap_init(TSS_HCONTEXT tspContext, + TSS_HOBJECT obj_parent, + TSS_HOBJECT obj_child, + TSS_BOOL requirements, + TPM_COMMAND_CODE command, + TPM_ENTITY_TYPE entity_type, + struct authsess **xsess) +{ + TSS_RESULT result; + TSS_BOOL authdatausage = FALSE, req_auth = TRUE, get_child_auth = TRUE, secret_set = FALSE; + BYTE hmacBlob[2 * sizeof(TPM_DIGEST)]; + UINT64 offset; + TSS_BOOL new_secret = TR_SECRET_CTX_NOT_NEW; + struct authsess *sess; + + if ((sess = calloc(1, sizeof(struct authsess))) == NULL) { + LogError("malloc of %zd bytes failed", sizeof(struct authsess)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + switch (command) { + /* Parent is Key for the cases below */ + case TPM_ORD_Delegate_CreateKeyDelegation: + case TPM_ORD_CreateWrapKey: + case TPM_ORD_CMK_CreateKey: + case TPM_ORD_Seal: + case TPM_ORD_Sealx: + case TPM_ORD_Unseal: + case TPM_ORD_ChangeAuth: + if ((result = obj_rsakey_get_policy(obj_parent, TSS_POLICY_USAGE, + &sess->hUsageParent, NULL))) + goto error; + break; + /* Parent is TPM for the cases below */ + case TPM_ORD_Delegate_CreateOwnerDelegation: + req_auth = FALSE; + /* fall through */ + case TPM_ORD_MakeIdentity: + case TPM_ORD_NV_DefineSpace: + if ((result = obj_tpm_get_policy(obj_parent, TSS_POLICY_USAGE, + &sess->hUsageParent))) + goto error; + break; + case TPM_ORD_ChangeAuthOwner: + /* Special case, ChangeAuthOwner is used to change Owner and SRK auth */ + if (obj_is_rsakey(obj_parent)) { + if ((result = obj_rsakey_get_policy(obj_parent, TSS_POLICY_USAGE, + &sess->hUsageParent, NULL))) + goto error; + } else { + if ((result = obj_tpm_get_policy(obj_parent, TSS_POLICY_USAGE, + &sess->hUsageParent))) + goto error; + } + break; + default: + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto error; + } + + if (requirements && !sess->hUsageParent) { + result = TSPERR(TSS_E_TSP_AUTHREQUIRED); + goto error; + } + + if (sess->hUsageParent) { + /* These are trousers callback functions which will be used to process the auth + * session. If the policy type is callback for hUsageParent, they will be + * overwritten by the application defined callback functions in the policy */ + sess->cb_xor.callback = authsess_callback_xor; + sess->cb_xor.appData = (PVOID)sess; + sess->cb_hmac.callback = authsess_callback_hmac; + sess->cb_hmac.appData = (PVOID)sess; + + /* XXX the parent object doesn't always hold the callbacks */ + if ((result = obj_policy_get_xsap_params(sess->hUsageParent, command, + &sess->entity_type, &sess->entityValueSize, + &sess->entityValue, + sess->parentSecret.authdata, &sess->cb_xor, + &sess->cb_hmac, NULL, &sess->parentMode, + new_secret))) + goto error; + } else + sess->parentMode = TSS_SECRET_MODE_NONE; + + switch (command) { + /* Child is a Key object */ + case TPM_ORD_CreateWrapKey: + case TPM_ORD_CMK_CreateKey: + if ((result = obj_rsakey_get_policies(obj_child, &sess->hUsageChild, + &sess->hMigChild, &authdatausage))) + goto error; + + if (authdatausage && !sess->hUsageChild) { + result = TSPERR(TSS_E_TSP_AUTHREQUIRED); + goto error; + } + + if (obj_rsakey_is_migratable(obj_child)) { + if (!sess->hMigChild) { + result = TSPERR(TSS_E_KEY_NO_MIGRATION_POLICY); + goto error; + } + + if ((result = obj_policy_get_xsap_params(sess->hMigChild, 0, NULL, NULL, + NULL, sess->encAuthMig.authdata, + NULL, NULL, NULL, &sess->mMode, + new_secret))) + goto error; + } + + if ((result = obj_rsakey_get_tcs_handle(obj_parent, &sess->obj_parent))) + goto error; + break; + /* Child is an Encdata object */ + case TPM_ORD_Unseal: +#ifdef TSS_BUILD_SEALX + case TPM_ORD_Sealx: + /* These may be overwritten down below, when obj_policy_get_xsap_params is called + * on the child usage policy */ + sess->cb_sealx.callback = sealx_mask_cb; + sess->cb_sealx.appData = (PVOID)sess; + /* fall through */ +#endif + case TPM_ORD_Seal: + if ((result = obj_encdata_get_policy(obj_child, TSS_POLICY_USAGE, + &sess->hUsageChild))) + goto error; + + if ((result = obj_rsakey_get_tcs_handle(obj_parent, &sess->obj_parent))) + goto error; + break; +#ifdef TSS_BUILD_NV + /* Child is an NV object */ + case TPM_ORD_NV_DefineSpace: + /* The requirements variable tells us whether nv object auth is required */ + req_auth = requirements; + + if (req_auth) { + if (sess->parentMode == TSS_SECRET_MODE_NONE) { + result = TSPERR(TSS_E_TSP_AUTHREQUIRED); + goto error; + } + + if ((result = obj_nvstore_get_policy(obj_child, TSS_POLICY_USAGE, + &sess->hUsageChild))) + goto error; + + /* According to the spec, we must fall back on the TSP context's policy for + * auth if none is set in the NV object */ + if (!sess->hUsageChild) { + if ((result = obj_context_get_policy(tspContext, TSS_POLICY_USAGE, + &sess->hUsageChild))) + goto error; + } + + if ((result = obj_policy_is_secret_set(sess->hUsageChild, &secret_set))) + goto error; + + if (!secret_set) { + result = TSPERR(TSS_E_TSP_AUTHREQUIRED); + goto error; + } + } else { + /* In this case, the TPM is owned, but we're creating a no-auth NV area */ + get_child_auth = FALSE; + } + + break; +#endif + /* Child is a Key object */ + case TPM_ORD_MakeIdentity: + if ((result = obj_rsakey_get_policy(obj_child, TSS_POLICY_USAGE, + &sess->hUsageChild, NULL))) + goto error; + break; + /* Child is a Policy object */ + case TPM_ORD_Delegate_CreateKeyDelegation: + case TPM_ORD_ChangeAuth: + if ((result = obj_rsakey_get_tcs_handle(obj_parent, &sess->obj_parent))) + goto error; + /* fall through */ + case TPM_ORD_Delegate_CreateOwnerDelegation: + case TPM_ORD_ChangeAuthOwner: + sess->hUsageChild = obj_child; + new_secret = TR_SECRET_CTX_NEW; + break; + default: + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto error; + } + + /* If req_auth is FALSE here, we don't actually need to set up an auth session, so returning + * is OK. At this point, authsess->pAuth is NULL, so the TCS API will not get any + * authdata. */ + if (req_auth == FALSE && sess->parentMode == TSS_SECRET_MODE_NONE) + goto done; + + if (get_child_auth) { + if ((result = obj_policy_get_xsap_params(sess->hUsageChild, 0, 0, NULL, NULL, + sess->encAuthUse.authdata, NULL, NULL, + &sess->cb_sealx, &sess->uMode, + new_secret))) + goto error; + } + + if ((result = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE), + (BYTE **)sess->nonceOddxSAP.nonce))) + goto error; + + sess->obj_child = obj_child; + sess->tspContext = tspContext; + sess->pAuth = &sess->auth; + sess->command = command; + +#ifdef TSS_BUILD_DELEGATION + /* if entityValue is set, we have a custom entity, i.e. delegation blob or row */ + if (sess->entityValue) { + /* DSAP's entity type was pulled from the policy in the authsess_xsap_init call + * above */ + if ((result = authsess_do_dsap(sess))) + goto error; + } +#endif + if (!sess->entityValue) { + sess->entity_type = entity_type; + if ((result = authsess_do_osap(sess))) + goto error; + } + + if ((result = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE), + (BYTE **)sess->auth.NonceOdd.nonce))) + goto error; + + /* We have both OSAP nonces, so calculate the shared secret if we're responsible for it */ + if (sess->parentMode != TSS_SECRET_MODE_CALLBACK) { + offset = 0; + Trspi_LoadBlob(&offset, sizeof(TPM_NONCE), hmacBlob, sess->nonceEvenxSAP.nonce); + Trspi_LoadBlob(&offset, sizeof(TPM_NONCE), hmacBlob, sess->nonceOddxSAP.nonce); + + if ((result = Trspi_HMAC(TSS_HASH_SHA1, sizeof(TPM_ENCAUTH), + sess->parentSecret.authdata, offset, hmacBlob, + sess->sharedSecret.digest))) + goto error; + } + + /* XXX What does a PurposeSecret of TRUE mean here? */ + if ((result = + ((TSS_RESULT (*)(PVOID, TSS_HOBJECT, TSS_HOBJECT, TSS_FLAG, + UINT32, BYTE *, BYTE *, BYTE *, BYTE *, UINT32, BYTE *, + BYTE *))sess->cb_xor.callback)(sess->cb_xor.appData, sess->hUsageParent, + sess->hUsageChild, TRUE, sizeof(TPM_DIGEST), + sess->auth.NonceEven.nonce, sess->auth.NonceOdd.nonce, + sess->nonceEvenxSAP.nonce, sess->nonceOddxSAP.nonce, + sizeof(TPM_ENCAUTH), sess->encAuthUse.authdata, + sess->encAuthMig.authdata))) + return result; + +done: + *xsess = sess; + + return TSS_SUCCESS; +error: + free(sess); + return result; +} + +TSS_RESULT +authsess_xsap_hmac(struct authsess *sess, TPM_DIGEST *digest) +{ + TSS_RESULT result; + + /* If no auth session was established using this authsess object, return success */ + if (!sess->pAuth) + return TSS_SUCCESS; + + /* XXX Placeholder for future continueAuthSession support: + * conditionally bump NonceOdd if continueAuthSession == TRUE here + */ + + if ((result = + ((TSS_RESULT (*)(PVOID, TSS_HOBJECT, TSS_BOOL, + UINT32, TSS_BOOL, UINT32, BYTE *, BYTE *, + BYTE *, BYTE *, UINT32, BYTE *, + BYTE *))sess->cb_hmac.callback)(sess->cb_hmac.appData, + sess->hUsageParent, TRUE, sess->command, + sess->auth.fContinueAuthSession, sizeof(TPM_NONCE), + sess->auth.NonceEven.nonce, + sess->auth.NonceOdd.nonce, + sess->nonceEvenxSAP.nonce, + sess->nonceOddxSAP.nonce, sizeof(TPM_DIGEST), + digest->digest, sess->auth.HMAC.authdata))) + return result; + + if (sess->hUsageParent) + obj_policy_dec_counter(sess->hUsageParent); + + if (sess->hUsageChild) + obj_policy_dec_counter(sess->hUsageChild); + + if (sess->hMigChild) + obj_policy_dec_counter(sess->hMigChild); + + return TSS_SUCCESS; +} + +TSS_RESULT +authsess_xsap_verify(struct authsess *sess, TPM_DIGEST *digest) +{ + /* If no auth session was established using this authsess object, return success */ + if (!sess->pAuth) + return TSS_SUCCESS; + + return ((TSS_RESULT (*)(PVOID, TSS_HOBJECT, TSS_BOOL, + UINT32, TSS_BOOL, UINT32, BYTE *, BYTE *, + BYTE *, BYTE *, UINT32, BYTE *, + BYTE *))sess->cb_hmac.callback)(sess->cb_hmac.appData, + sess->hUsageParent, FALSE, sess->command, + sess->auth.fContinueAuthSession, sizeof(TPM_NONCE), + sess->auth.NonceEven.nonce, + sess->auth.NonceOdd.nonce, + sess->nonceEvenxSAP.nonce, + sess->nonceOddxSAP.nonce, sizeof(TPM_DIGEST), + digest->digest, sess->auth.HMAC.authdata); +} + +TSS_RESULT +__tspi_free_resource(TSS_HCONTEXT tspContext, UINT32 handle, UINT32 resourceType) +{ + TSS_RESULT result = TSS_SUCCESS; +#ifdef TSS_BUILD_TSS12 + UINT32 version = 0; + + if ((result = obj_context_get_tpm_version(tspContext, &version))) + return result; + + if (version == 2) { + return TCS_API(tspContext)->FlushSpecific(tspContext, handle, resourceType); + } +#endif + + switch (resourceType) { + case TPM_RT_KEY: + result = TCS_API(tspContext)->EvictKey(tspContext, handle); + break; + case TPM_RT_AUTH: + result = TCS_API(tspContext)->TerminateHandle(tspContext, handle); + break; + default: + LogDebugFn("Trying to free TPM 1.2 resource type 0x%x on 1.1 TPM!", + resourceType); + result = TSPERR(TSS_E_INTERNAL_ERROR); + break; + } + + return result; +} + +void +authsess_free(struct authsess *xsap) +{ + if (xsap) { + if (xsap->auth.AuthHandle && xsap->auth.fContinueAuthSession) + (void)__tspi_free_resource(xsap->tspContext, xsap->auth.AuthHandle, TPM_RT_AUTH); + + free(xsap->entityValue); + free(xsap); + xsap = NULL; + } +} + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_OIAP(TSS_HCONTEXT tspContext, /* in */ + TCS_AUTHHANDLE* authHandle, /* out */ + TPM_NONCE* nonce0) /* out */ +{ + TSS_RESULT result; + UINT32 decLen = 0; + BYTE *dec = NULL; + UINT64 offset; + TCS_HANDLE handlesLen = 0; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_OIAP, 0, NULL, NULL, + &handlesLen, NULL, NULL, NULL, &decLen, &dec))) + return result; + + if (decLen != sizeof(TCS_AUTHHANDLE) + sizeof(TPM_NONCE)) + return TSPERR(TSS_E_INTERNAL_ERROR); + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, authHandle, dec); + Trspi_UnloadBlob_NONCE(&offset, dec, nonce0); + + return result; +} + +TSS_RESULT +Transport_OSAP(TSS_HCONTEXT tspContext, /* in */ + TPM_ENTITY_TYPE entityType, /* in */ + UINT32 entityValue, /* in */ + TPM_NONCE* nonceOddOSAP, /* in */ + TCS_AUTHHANDLE* authHandle, /* out */ + TPM_NONCE* nonceEven, /* out */ + TPM_NONCE* nonceEvenOSAP) /* out */ +{ + TSS_RESULT result; + UINT32 decLen = 0; + BYTE *dec = NULL; + UINT64 offset; + TCS_HANDLE handlesLen = 0; + BYTE data[sizeof(UINT16) + sizeof(UINT32) + sizeof(TPM_NONCE)]; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + offset = 0; + Trspi_LoadBlob_UINT16(&offset, entityType, data); + Trspi_LoadBlob_UINT32(&offset, entityValue, data); + Trspi_LoadBlob_NONCE(&offset, data, nonceOddOSAP); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_OSAP, sizeof(data), data, + NULL, &handlesLen, NULL, NULL, NULL, &decLen, + &dec))) + return result; + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, authHandle, dec); + Trspi_UnloadBlob_NONCE(&offset, dec, nonceEven); + Trspi_UnloadBlob_NONCE(&offset, dec, nonceEvenOSAP); + + return TSS_SUCCESS; +} + +TSS_RESULT +Transport_TerminateHandle(TSS_HCONTEXT tspContext, /* in */ + TCS_AUTHHANDLE handle) /* in */ +{ + TSS_RESULT result; + TCS_HANDLE handlesLen = 0, *handles; + + /* Call ExecuteTransport */ + handlesLen = 1; + if ((handles = malloc(sizeof(TCS_HANDLE))) == NULL) { + LogError("malloc of %zd bytes failed", sizeof(TCS_HANDLE)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + *handles = handle; + + result = obj_context_transport_execute(tspContext, TPM_ORD_Terminate_Handle, 0, NULL, + NULL, &handlesLen, &handles, NULL, NULL, NULL, NULL); + + return result; +} +#endif diff --git a/src/tspi/tsp_bind.c b/src/tspi/tsp_bind.c new file mode 100644 index 0000000..38e30ff --- /dev/null +++ b/src/tspi/tsp_bind.c @@ -0,0 +1,92 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + + +#include <stdlib.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_UnBind(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + UINT32 inDataSize, /* in */ + BYTE * inData, /* in */ + TPM_AUTH * privAuth, /* in, out */ + UINT32 * outDataSize, /* out */ + BYTE ** outData) /* out */ +{ + TSS_RESULT result; + UINT32 handlesLen, dataLen, decLen; + TCS_HANDLE *handles, handle; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + BYTE *dec, *data; + UINT64 offset; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + handlesLen = 1; + handle = keyHandle; + handles = &handle; + + dataLen = sizeof(UINT32) + inDataSize; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, inDataSize, data); + Trspi_LoadBlob(&offset, inDataSize, data, inData); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_UnBind, dataLen, data, + &pubKeyHash, &handlesLen, &handles, + privAuth, NULL, &decLen, &dec))) { + free(data); + return result; + } + free(data); + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, outDataSize, dec); + + if ((*outData = malloc(*outDataSize)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *outDataSize); + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *outDataSize, dec, *outData); + + free(dec); + + return TSS_SUCCESS; +} +#endif + diff --git a/src/tspi/tsp_caps.c b/src/tspi/tsp_caps.c new file mode 100644 index 0000000..f06fbd6 --- /dev/null +++ b/src/tspi/tsp_caps.c @@ -0,0 +1,176 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <errno.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +internal_GetCap(TSS_HCONTEXT tspContext, TSS_FLAG capArea, UINT32 subCap, + UINT32 * respSize, BYTE ** respData) +{ + UINT64 offset = 0; + TSS_VERSION v = INTERNAL_CAP_VERSION; + TSS_BOOL bValue = FALSE; + UINT32 u32value = 0; + + switch (capArea) { + case TSS_TSPCAP_VERSION: + if ((*respData = calloc_tspi(tspContext, sizeof(TSS_VERSION))) == NULL) { + LogError("malloc of %zd bytes failed", sizeof(TSS_VERSION)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + Trspi_LoadBlob_TSS_VERSION(&offset, *respData, v); + *respSize = offset; + break; + case TSS_TSPCAP_ALG: + switch (subCap) { + case TSS_ALG_RSA: + *respSize = sizeof(TSS_BOOL); + bValue = INTERNAL_CAP_TSP_ALG_RSA; + break; + case TSS_ALG_AES: + *respSize = sizeof(TSS_BOOL); + bValue = INTERNAL_CAP_TSP_ALG_AES; + break; + case TSS_ALG_SHA: + *respSize = sizeof(TSS_BOOL); + bValue = INTERNAL_CAP_TSP_ALG_SHA; + break; + case TSS_ALG_HMAC: + *respSize = sizeof(TSS_BOOL); + bValue = INTERNAL_CAP_TSP_ALG_HMAC; + break; + case TSS_ALG_DES: + *respSize = sizeof(TSS_BOOL); + bValue = INTERNAL_CAP_TSP_ALG_DES; + break; + case TSS_ALG_3DES: + *respSize = sizeof(TSS_BOOL); + bValue = INTERNAL_CAP_TSP_ALG_3DES; + break; + case TSS_ALG_DEFAULT: + *respSize = sizeof(UINT32); + u32value = INTERNAL_CAP_TSP_ALG_DEFAULT; + break; + case TSS_ALG_DEFAULT_SIZE: + *respSize = sizeof(UINT32); + u32value = INTERNAL_CAP_TSP_ALG_DEFAULT_SIZE; + break; + default: + LogError("Unknown TSP subCap: %u", subCap); + return TSPERR(TSS_E_BAD_PARAMETER); + } + + if ((*respData = calloc_tspi(tspContext, *respSize)) == NULL) { + LogError("malloc of %u bytes failed", *respSize); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + if (*respSize == sizeof(TSS_BOOL)) + *(TSS_BOOL *)respData = bValue; + else + *(UINT32 *)respData = u32value; + break; + case TSS_TSPCAP_PERSSTORAGE: + if ((*respData = calloc_tspi(tspContext, sizeof(TSS_BOOL))) == NULL) { + LogError("malloc of %zd bytes failed", sizeof(TSS_BOOL)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + *respSize = sizeof(TSS_BOOL); + (*respData)[0] = INTERNAL_CAP_TSP_PERSSTORAGE; + break; + case TSS_TSPCAP_RETURNVALUE_INFO: + if (subCap != TSS_TSPCAP_PROP_RETURNVALUE_INFO) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((*respData = calloc_tspi(tspContext, sizeof(UINT32))) == NULL) { + LogError("malloc of %zd bytes failed", sizeof(UINT32)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + *respSize = sizeof(UINT32); + *(UINT32 *)(*respData) = INTERNAL_CAP_TSP_RETURNVALUE_INFO; + break; + case TSS_TSPCAP_PLATFORM_INFO: + switch (subCap) { + case TSS_TSPCAP_PLATFORM_TYPE: + if ((*respData = calloc_tspi(tspContext, sizeof(UINT32))) == NULL) { + LogError("malloc of %zd bytes failed", sizeof(UINT32)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + *respSize = sizeof(UINT32); + *(UINT32 *)(*respData) = INTERNAL_CAP_TSP_PLATFORM_TYPE; + break; + case TSS_TSPCAP_PLATFORM_VERSION: + if ((*respData = calloc_tspi(tspContext, sizeof(UINT32))) == NULL) { + LogError("malloc of %zd bytes failed", sizeof(UINT32)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + *respSize = sizeof(UINT32); + *(UINT32 *)(*respData) = INTERNAL_CAP_TSP_PLATFORM_VERSION; + break; + default: + return TSPERR(TSS_E_BAD_PARAMETER); + } + case TSS_TSPCAP_MANUFACTURER: + switch (subCap) { + case TSS_TSPCAP_PROP_MANUFACTURER_ID: + if ((*respData = calloc_tspi(tspContext, sizeof(UINT32))) == NULL) { + LogError("malloc of %zd bytes failed", sizeof(UINT32)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + *respSize = sizeof(UINT32); + *(UINT32 *)(*respData) = INTERNAL_CAP_MANUFACTURER_ID; + break; + case TSS_TSPCAP_PROP_MANUFACTURER_STR: + { + BYTE str[] = INTERNAL_CAP_MANUFACTURER_STR; + + if ((*respData = calloc_tspi(tspContext, + INTERNAL_CAP_MANUFACTURER_STR_LEN)) == NULL) { + LogError("malloc of %d bytes failed", + INTERNAL_CAP_MANUFACTURER_STR_LEN); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + *respSize = INTERNAL_CAP_MANUFACTURER_STR_LEN; + memcpy(*respData, str, INTERNAL_CAP_MANUFACTURER_STR_LEN); + break; + } + default: + return TSPERR(TSS_E_BAD_PARAMETER); + } + default: + return TSPERR(TSS_E_BAD_PARAMETER); + } + + return TSS_SUCCESS; +} diff --git a/src/tspi/tsp_caps_tpm.c b/src/tspi/tsp_caps_tpm.c new file mode 100644 index 0000000..1203dbe --- /dev/null +++ b/src/tspi/tsp_caps_tpm.c @@ -0,0 +1,167 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +/* + * This function provides a funnel through which all the TCSP_SetCapability requests can be + * sent. This will keep the owner auth code from being duplicated around the TSP. + */ +TSS_RESULT +TSP_SetCapability(TSS_HCONTEXT tspContext, + TSS_HTPM hTPM, + TSS_HPOLICY hTPMPolicy, + TPM_CAPABILITY_AREA tcsCapArea, + UINT32 subCap, + TSS_BOOL value) +{ + TSS_RESULT result; + Trspi_HashCtx hashCtx; + TPM_DIGEST digest; + TPM_AUTH auth; + + subCap = endian32(subCap); + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_SetCapability); + result |= Trspi_Hash_UINT32(&hashCtx, tcsCapArea); + result |= Trspi_Hash_UINT32(&hashCtx, (UINT32)sizeof(UINT32)); + result |= Trspi_HashUpdate(&hashCtx, (UINT32)sizeof(UINT32), (BYTE *)&subCap); + result |= Trspi_Hash_UINT32(&hashCtx, (UINT32)sizeof(TSS_BOOL)); + result |= Trspi_Hash_BOOL(&hashCtx, value); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_SetCapability, hTPMPolicy, FALSE, + &digest, &auth))) + return result; + + if ((result = TCS_API(tspContext)->SetCapability(tspContext, tcsCapArea, sizeof(UINT32), + (BYTE *)&subCap, sizeof(TSS_BOOL), + (BYTE *)&value, &auth))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_SetCapability); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + return obj_policy_validate_auth_oiap(hTPMPolicy, &digest, &auth); +} + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_GetTPMCapability(TSS_HCONTEXT tspContext, /* in */ + TPM_CAPABILITY_AREA capArea, /* in */ + UINT32 subCapLen, /* in */ + BYTE* subCap, /* in */ + UINT32* respLen, /* out */ + BYTE** resp) /* out */ +{ + TSS_RESULT result; + UINT32 decLen = 0, dataLen; + BYTE *dec = NULL; + UINT64 offset; + TCS_HANDLE handlesLen = 0; + BYTE *data; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + dataLen = (2 * sizeof(UINT32)) + subCapLen; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, capArea, data); + Trspi_LoadBlob_UINT32(&offset, subCapLen, data); + Trspi_LoadBlob(&offset, subCapLen, data, subCap); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetCapability, dataLen, + data, NULL, &handlesLen, NULL, NULL, NULL, + &decLen, &dec))) { + free(data); + return result; + } + free(data); + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, respLen, dec); + + if ((*resp = malloc(*respLen)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *respLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + Trspi_UnloadBlob(&offset, *respLen, dec, *resp); + free(dec); + + return result; + +} + +TSS_RESULT +Transport_SetCapability(TSS_HCONTEXT tspContext, /* in */ + TCPA_CAPABILITY_AREA capArea, /* in */ + UINT32 subCapSize, /* in */ + BYTE * subCap, /* in */ + UINT32 valueSize, /* in */ + BYTE * value, /* in */ + TPM_AUTH *ownerAuth) /* in, out */ +{ + TSS_RESULT result; + UINT32 dataLen; + UINT64 offset; + TCS_HANDLE handlesLen = 0; + BYTE *data; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + dataLen = (3 * sizeof(UINT32)) + subCapSize + valueSize; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, capArea, data); + Trspi_LoadBlob_UINT32(&offset, subCapSize, data); + Trspi_LoadBlob(&offset, subCapSize, data, subCap); + Trspi_LoadBlob_UINT32(&offset, valueSize, data); + Trspi_LoadBlob(&offset, valueSize, data, value); + + result = obj_context_transport_execute(tspContext, TPM_ORD_SetCapability, dataLen, data, + NULL, &handlesLen, NULL, NULL, NULL, NULL, NULL); + + free(data); + return result; +} +#endif diff --git a/src/tspi/tsp_certify.c b/src/tspi/tsp_certify.c new file mode 100644 index 0000000..6a586d9 --- /dev/null +++ b/src/tspi/tsp_certify.c @@ -0,0 +1,108 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + + +#include <stdlib.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_CertifyKey(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE certHandle, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + TPM_NONCE * antiReplay, /* in */ + TPM_AUTH * certAuth, /* in, out */ + TPM_AUTH * keyAuth, /* in, out */ + UINT32 * CertifyInfoSize, /* out */ + BYTE ** CertifyInfo, /* out */ + UINT32 * outDataSize, /* out */ + BYTE ** outData) /* out */ +{ + TSS_RESULT result; + UINT32 handlesLen, decLen; + TCS_HANDLE *handles, handle[2]; + BYTE *dec = NULL; + TPM_DIGEST pubKeyHash1, pubKeyHash2; + Trspi_HashCtx hashCtx; + UINT64 offset; + BYTE data[sizeof(TPM_NONCE)]; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(certHandle, pubKeyHash1.digest))) + return result; + + if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash2.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash1.digest); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash2.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash1.digest))) + return result; + + handlesLen = 2; + handle[0] = certHandle; + handle[1] = keyHandle; + handles = &handle[0]; + + offset = 0; + Trspi_LoadBlob_NONCE(&offset, data, antiReplay); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_CertifyKey, sizeof(data), + data, &pubKeyHash1, &handlesLen, &handles, + certAuth, keyAuth, &decLen, &dec))) + return result; + + offset = 0; + Trspi_UnloadBlob_CERTIFY_INFO(&offset, dec, NULL); + *CertifyInfoSize = offset; + + if ((*CertifyInfo = malloc(*CertifyInfoSize)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *CertifyInfoSize); + *CertifyInfoSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_UnloadBlob(&offset, *CertifyInfoSize, dec, *CertifyInfo); + Trspi_UnloadBlob_UINT32(&offset, outDataSize, dec); + + if ((*outData = malloc(*outDataSize)) == NULL) { + free(*CertifyInfo); + *CertifyInfo = NULL; + *CertifyInfoSize = 0; + free(dec); + LogError("malloc of %u bytes failed", *outDataSize); + *outDataSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *outDataSize, dec, *outData); + + free(dec); + + return result; +} +#endif + diff --git a/src/tspi/tsp_changeauth.c b/src/tspi/tsp_changeauth.c new file mode 100644 index 0000000..7b194fc --- /dev/null +++ b/src/tspi/tsp_changeauth.c @@ -0,0 +1,470 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <errno.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" +#include "authsess.h" + + +TSS_RESULT +Trspi_UnloadBlob_STORED_DATA(UINT64 *offset, BYTE *blob, TCPA_STORED_DATA *data) +{ + Trspi_UnloadBlob_TCPA_VERSION(offset, blob, &data->ver); + Trspi_UnloadBlob_UINT32(offset, &data->sealInfoSize, blob); + + if (data->sealInfoSize > 0) { + data->sealInfo = malloc(data->sealInfoSize); + if (data->sealInfo == NULL) { + LogError("malloc of %d bytes failed.", data->sealInfoSize); + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(offset, data->sealInfoSize, blob, data->sealInfo); + } else { + data->sealInfo = NULL; + } + + Trspi_UnloadBlob_UINT32(offset, &data->encDataSize, blob); + + if (data->encDataSize > 0) { + data->encData = malloc(data->encDataSize); + if (data->encData == NULL) { + LogError("malloc of %d bytes failed.", data->encDataSize); + free(data->sealInfo); + data->sealInfo = NULL; + return TSPERR(TSS_E_OUTOFMEMORY); + } + + Trspi_UnloadBlob(offset, data->encDataSize, blob, data->encData); + } else { + data->encData = NULL; + } + + return TSS_SUCCESS; +} + +void +Trspi_LoadBlob_STORED_DATA(UINT64 *offset, BYTE *blob, TCPA_STORED_DATA *data) +{ + Trspi_LoadBlob_TCPA_VERSION(offset, blob, data->ver); + Trspi_LoadBlob_UINT32(offset, data->sealInfoSize, blob); + Trspi_LoadBlob(offset, data->sealInfoSize, blob, data->sealInfo); + Trspi_LoadBlob_UINT32(offset, data->encDataSize, blob); + Trspi_LoadBlob(offset, data->encDataSize, blob, data->encData); +} + +TSS_RESULT +changeauth_owner(TSS_HCONTEXT tspContext, + TSS_HOBJECT hObjectToChange, + TSS_HOBJECT hParentObject, + TSS_HPOLICY hNewPolicy) +{ + TPM_DIGEST digest; + TSS_RESULT result; + Trspi_HashCtx hashCtx; + struct authsess *xsap = NULL; + + if ((result = authsess_xsap_init(tspContext, hObjectToChange, hNewPolicy, + TSS_AUTH_POLICY_REQUIRED, TPM_ORD_ChangeAuthOwner, + TPM_ET_OWNER, &xsap))) + return result; + + /* calculate auth data */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthOwner); + result |= Trspi_Hash_UINT16(&hashCtx, TCPA_PID_ADCP); + result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata); + result |= Trspi_Hash_UINT16(&hashCtx, TCPA_ET_OWNER); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + if ((result = authsess_xsap_hmac(xsap, &digest))) + goto error; + + if ((result = TCS_API(tspContext)->ChangeAuthOwner(tspContext, TCPA_PID_ADCP, + &xsap->encAuthUse, TPM_ET_OWNER, + xsap->pAuth))) + goto error; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthOwner); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + result = authsess_xsap_verify(xsap, &digest); +error: + authsess_free(xsap); + + return result; +} + +TSS_RESULT +changeauth_srk(TSS_HCONTEXT tspContext, + TSS_HOBJECT hObjectToChange, + TSS_HOBJECT hParentObject, + TSS_HPOLICY hNewPolicy) +{ + TPM_DIGEST digest; + TSS_RESULT result; + Trspi_HashCtx hashCtx; + struct authsess *xsap = NULL; + + + if ((result = authsess_xsap_init(tspContext, hParentObject, hNewPolicy, + TSS_AUTH_POLICY_REQUIRED, TPM_ORD_ChangeAuthOwner, + TPM_ET_OWNER, &xsap))) + return result; + + /* calculate auth data */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthOwner); + result |= Trspi_Hash_UINT16(&hashCtx, TCPA_PID_ADCP); + result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata); + result |= Trspi_Hash_UINT16(&hashCtx, TCPA_ET_SRK); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + if ((result = authsess_xsap_hmac(xsap, &digest))) + goto error; + + if ((result = TCS_API(tspContext)->ChangeAuthOwner(tspContext, TCPA_PID_ADCP, + &xsap->encAuthUse, TPM_ET_SRK, + xsap->pAuth))) + goto error; + + /* Validate the Auths */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthOwner); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + result = authsess_xsap_verify(xsap, &digest); +error: + authsess_free(xsap); + + return result; +} + +TSS_RESULT +changeauth_encdata(TSS_HCONTEXT tspContext, + TSS_HOBJECT hObjectToChange, + TSS_HOBJECT hParentObject, + TSS_HPOLICY hNewPolicy) +{ + TPM_DIGEST digest; + TSS_RESULT result; + Trspi_HashCtx hashCtx; + TSS_HPOLICY hPolicy; + TCS_KEY_HANDLE keyHandle; + UINT64 offset; + struct authsess *xsap = NULL; + TPM_STORED_DATA storedData; + UINT32 dataBlobLength, newEncSize; + BYTE *dataBlob, *newEncData; + TPM_AUTH auth2; + + /* get the secret for the parent */ + if ((result = obj_encdata_get_policy(hObjectToChange, TSS_POLICY_USAGE, &hPolicy))) + return result; + + /* get the data Object */ + if ((result = obj_encdata_get_data(hObjectToChange, &dataBlobLength, &dataBlob))) + return result; + + offset = 0; + if ((result = Trspi_UnloadBlob_STORED_DATA(&offset, dataBlob, &storedData))) + return result; + + if ((result = obj_rsakey_get_tcs_handle(hParentObject, &keyHandle))) + return result; + + if ((result = authsess_xsap_init(tspContext, hParentObject, hNewPolicy, + TSS_AUTH_POLICY_REQUIRED, TPM_ORD_ChangeAuth, + TPM_ET_KEYHANDLE, &xsap))) + return result; + + /* caluculate auth data */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuth); + result |= Trspi_Hash_UINT16(&hashCtx, TPM_PID_ADCP); + result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata); + result |= Trspi_Hash_UINT16(&hashCtx, TPM_ET_DATA); + result |= Trspi_Hash_UINT32(&hashCtx, storedData.encDataSize); + result |= Trspi_HashUpdate(&hashCtx, storedData.encDataSize, storedData.encData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + if ((result = authsess_xsap_hmac(xsap, &digest))) + goto error; + + if ((result = secret_PerformAuth_OIAP(hObjectToChange, TPM_ORD_ChangeAuth, + hPolicy, FALSE, &digest, &auth2))) + goto error; + + if ((result = TCS_API(tspContext)->ChangeAuth(tspContext, keyHandle, TPM_PID_ADCP, + &xsap->encAuthUse, TPM_ET_DATA, + storedData.encDataSize, storedData.encData, + xsap->pAuth, &auth2, &newEncSize, + &newEncData))) + goto error; + + /* Validate the Auths */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuth); + result |= Trspi_Hash_UINT32(&hashCtx, newEncSize); + result |= Trspi_HashUpdate(&hashCtx, newEncSize, newEncData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + if ((result = authsess_xsap_verify(xsap, &digest))) + goto error; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth2))) + goto error; + + memcpy(storedData.encData, newEncData, newEncSize); + free(newEncData); + storedData.encDataSize = newEncSize; + + offset = 0; + Trspi_LoadBlob_STORED_DATA(&offset, dataBlob, &storedData); + + result = obj_encdata_set_data(hObjectToChange, offset, dataBlob); + +error: + authsess_free(xsap); + free(storedData.sealInfo); + free(storedData.encData); + + return result; + +} + +TSS_RESULT +changeauth_key(TSS_HCONTEXT tspContext, + TSS_HOBJECT hObjectToChange, + TSS_HOBJECT hParentObject, + TSS_HPOLICY hNewPolicy) +{ + TPM_DIGEST digest; + Trspi_HashCtx hashCtx; + TSS_RESULT result; + TSS_KEY keyToChange; + TCS_KEY_HANDLE keyHandle; + struct authsess *xsap = NULL; + UINT32 objectLength; + TSS_HPOLICY hPolicy; + BYTE *keyBlob; + UINT32 newEncSize; + BYTE *newEncData; + TPM_AUTH auth2; + UINT64 offset; + + + if ((result = obj_rsakey_get_blob(hObjectToChange, &objectLength, &keyBlob))) + return result; + + offset = 0; + if ((result = UnloadBlob_TSS_KEY(&offset, keyBlob, &keyToChange))) { + LogDebug("UnloadBlob_TSS_KEY failed. " + "result=0x%x", result); + return result; + } + + if ((result = obj_rsakey_get_policy(hObjectToChange, TSS_POLICY_USAGE, &hPolicy, NULL))) + return result; + + if ((result = obj_rsakey_get_tcs_handle(hParentObject, &keyHandle))) + return result; + + if ((result = authsess_xsap_init(tspContext, hParentObject, hNewPolicy, + TSS_AUTH_POLICY_REQUIRED, TPM_ORD_ChangeAuth, + keyHandle == TPM_KEYHND_SRK ? + TPM_ET_SRK : TPM_ET_KEYHANDLE, &xsap))) + return result; + + /* caluculate auth data */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuth); + result |= Trspi_Hash_UINT16(&hashCtx, TCPA_PID_ADCP); + result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata); + result |= Trspi_Hash_UINT16(&hashCtx, TCPA_ET_KEY); + result |= Trspi_Hash_UINT32(&hashCtx, keyToChange.encSize); + result |= Trspi_HashUpdate(&hashCtx, keyToChange.encSize, + keyToChange.encData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + if ((result = authsess_xsap_hmac(xsap, &digest))) + goto error; + + if ((result = secret_PerformAuth_OIAP(hObjectToChange, TPM_ORD_ChangeAuth, + hPolicy, FALSE, &digest, &auth2))) + goto error; + + if ((result = TCS_API(tspContext)->ChangeAuth(tspContext, keyHandle, TPM_PID_ADCP, + &xsap->encAuthUse, TPM_ET_KEY, + keyToChange.encSize, keyToChange.encData, + xsap->pAuth, &auth2, &newEncSize, + &newEncData))) + goto error; + + /* Validate the Auths */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuth); + result |= Trspi_Hash_UINT32(&hashCtx, newEncSize); + result |= Trspi_HashUpdate(&hashCtx, newEncSize, newEncData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + if ((result = authsess_xsap_verify(xsap, &digest))) + goto error; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth2))) + return result; + + memcpy(keyToChange.encData, newEncData, newEncSize); + free(newEncData); + + offset = 0; + LoadBlob_TSS_KEY(&offset, keyBlob, &keyToChange); + objectLength = offset; + + result = obj_rsakey_set_tcpakey(hObjectToChange, objectLength, keyBlob); +error: + authsess_free(xsap); + + return result; +} + + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_ChangeAuth(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE parentHandle, /* in */ + TCPA_PROTOCOL_ID protocolID, /* in */ + TCPA_ENCAUTH *newAuth, /* in */ + TCPA_ENTITY_TYPE entityType, /* in */ + UINT32 encDataSize, /* in */ + BYTE * encData, /* in */ + TPM_AUTH * ownerAuth, /* in, out */ + TPM_AUTH * entityAuth, /* in, out */ + UINT32 * outDataSize, /* out */ + BYTE ** outData) /* out */ +{ + TSS_RESULT result; + UINT32 handlesLen, dataLen, decLen; + TCS_HANDLE *handles, handle; + BYTE *dec = NULL; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + UINT64 offset; + BYTE *data; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(parentHandle, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + handlesLen = 1; + handle = parentHandle; + handles = &handle; + + dataLen = sizeof(TCPA_PROTOCOL_ID) + sizeof(TCPA_ENCAUTH) + + sizeof(TCPA_ENTITY_TYPE) + + sizeof(UINT32) + + encDataSize; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob_UINT16(&offset, protocolID, data); + Trspi_LoadBlob(&offset, sizeof(TCPA_ENCAUTH), data, newAuth->authdata); + Trspi_LoadBlob_UINT16(&offset, entityType, data); + Trspi_LoadBlob_UINT32(&offset, encDataSize, data); + Trspi_LoadBlob(&offset, encDataSize, data, encData); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_ChangeAuth, dataLen, data, + &pubKeyHash, &handlesLen, &handles, + ownerAuth, entityAuth, &decLen, &dec))) { + free(data); + return result; + } + free(data); + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, outDataSize, dec); + + if ((*outData = malloc(*outDataSize)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *outDataSize); + *outDataSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *outDataSize, dec, *outData); + + free(dec); + + return result; +} + +TSS_RESULT +Transport_ChangeAuthOwner(TSS_HCONTEXT tspContext, /* in */ + TCPA_PROTOCOL_ID protocolID, /* in */ + TCPA_ENCAUTH *newAuth, /* in */ + TCPA_ENTITY_TYPE entityType, /* in */ + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0; + UINT64 offset; + BYTE data[sizeof(TCPA_PROTOCOL_ID) + sizeof(TCPA_ENCAUTH) + sizeof(TCPA_ENTITY_TYPE)]; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + offset = 0; + Trspi_LoadBlob_UINT16(&offset, protocolID, data); + Trspi_LoadBlob(&offset, sizeof(TCPA_ENCAUTH), data, newAuth->authdata); + Trspi_LoadBlob_UINT16(&offset, entityType, data); + + return obj_context_transport_execute(tspContext, TPM_ORD_ChangeAuthOwner, sizeof(data), + data, NULL, &handlesLen, NULL, ownerAuth, NULL, NULL, + NULL); +} +#endif diff --git a/src/tspi/tsp_context_mem.c b/src/tspi/tsp_context_mem.c new file mode 100644 index 0000000..13f1243 --- /dev/null +++ b/src/tspi/tsp_context_mem.c @@ -0,0 +1,258 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "memmgr.h" +#include "tsplog.h" +#include "obj.h" + +static struct memTable * +__tspi_createTable() +{ + struct memTable *table = NULL; + /* + * No table has yet been created to hold the memory allocations of + * this context, so we need to create one + */ + table = calloc(1, sizeof(struct memTable)); + if (table == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(struct memTable)); + return NULL; + } + return (table); +} + +/* caller needs to lock memtable lock */ +struct memTable * +getTable(TSS_HCONTEXT tspContext) +{ + struct memTable *tmp; + + for (tmp = SpiMemoryTable; tmp; tmp = tmp->nextTable) + if (tmp->tspContext == tspContext) + return tmp; + + return NULL; +} + +/* caller needs to lock memtable lock */ +static void +__tspi_addTable(struct memTable *new) +{ + struct memTable *tmp = SpiMemoryTable; + + /* base case, this is the first table */ + if (SpiMemoryTable == NULL) { + SpiMemoryTable = new; + return; + } + + /* else add @new onto the end */ + for (; tmp; tmp = tmp->nextTable) + if (tmp->nextTable == NULL) { + tmp->nextTable = new; + break; + } +} + +/* caller needs to lock memtable lock and be sure the context mem slot for + * @tspContext exists before calling. + */ +void +__tspi_addEntry(TSS_HCONTEXT tspContext, struct memEntry *new) +{ + struct memTable *tmp = getTable(tspContext); + struct memEntry *tmp_entry; + + if (tmp == NULL) { + if ((tmp = __tspi_createTable()) == NULL) + return; + tmp->tspContext = tspContext; + __tspi_addTable(tmp); + } + + tmp_entry = tmp->entries; + + if (tmp->entries == NULL) { + tmp->entries = new; + return; + } + + /* else tack @new onto the end */ + for (; tmp_entry; tmp_entry = tmp_entry->nextEntry) { + if (tmp_entry->nextEntry == NULL) { + tmp_entry->nextEntry = new; + break; + } + } +} + +/* caller needs to lock memtable lock */ +TSS_RESULT +__tspi_freeTable(TSS_HCONTEXT tspContext) +{ + struct memTable *prev = NULL, *index = NULL, *next = NULL; + struct memEntry *entry = NULL, *entry_next = NULL; + + for(index = SpiMemoryTable; index; index = index->nextTable) { + next = index->nextTable; + if (index->tspContext == tspContext) { + for (entry = index->entries; entry; entry = entry_next) { + /* this needs to be set before we do free(entry) */ + entry_next = entry->nextEntry; + free(entry->memPointer); + free(entry); + } + + if (prev != NULL) + prev->nextTable = next; + else + SpiMemoryTable = NULL; + + free(index); + break; + } + prev = index; + } + + return TSS_SUCCESS; +} + +TSS_RESULT +__tspi_freeEntry(struct memTable *table, void *pointer) +{ + struct memEntry *index = NULL; + struct memEntry *prev = NULL; + struct memEntry *toKill = NULL; + + for (index = table->entries; index; prev = index, index = index->nextEntry) { + if (index->memPointer == pointer) { + toKill = index; + if (prev == NULL) + table->entries = toKill->nextEntry; + else + prev->nextEntry = toKill->nextEntry; + + free(pointer); + free(toKill); + return TSS_SUCCESS; + } + } + + return TSPERR(TSS_E_INVALID_RESOURCE); +} + +TSS_RESULT +__tspi_add_mem_entry(TSS_HCONTEXT tspContext, void *allocd_mem) +{ + struct memEntry *newEntry = calloc(1, sizeof(struct memEntry)); + if (newEntry == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(struct memEntry)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + newEntry->memPointer = allocd_mem; + + MUTEX_LOCK(memtable_lock); + + __tspi_addEntry(tspContext, newEntry); + + MUTEX_UNLOCK(memtable_lock); + + return TSS_SUCCESS; +} + +/* + * calloc_tspi will be called by functions outside of this file. All locking + * is done here. + */ +void * +calloc_tspi(TSS_HCONTEXT tspContext, UINT32 howMuch) +{ + struct memTable *table = NULL; + struct memEntry *newEntry = NULL; + + MUTEX_LOCK(memtable_lock); + + table = getTable(tspContext); + if (table == NULL) { + if ((table = __tspi_createTable()) == NULL) { + MUTEX_UNLOCK(memtable_lock); + return NULL; + } + table->tspContext = tspContext; + __tspi_addTable(table); + } + + newEntry = calloc(1, sizeof(struct memEntry)); + if (newEntry == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(struct memEntry)); + MUTEX_UNLOCK(memtable_lock); + return NULL; + } + + newEntry->memPointer = calloc(1, howMuch); + if (newEntry->memPointer == NULL) { + LogError("malloc of %d bytes failed.", howMuch); + free(newEntry); + MUTEX_UNLOCK(memtable_lock); + return NULL; + } + + /* this call must happen inside the lock or else another thread could + * remove the context mem slot, causing a segfault + */ + __tspi_addEntry(tspContext, newEntry); + + MUTEX_UNLOCK(memtable_lock); + + return newEntry->memPointer; +} + +/* + * free_tspi will be called by functions outside of this file. All locking + * is done here. + */ +TSS_RESULT +free_tspi(TSS_HCONTEXT tspContext, void *memPointer) +{ + struct memTable *index; + TSS_RESULT result; + + MUTEX_LOCK(memtable_lock); + + if (memPointer == NULL) { + result = __tspi_freeTable(tspContext); + MUTEX_UNLOCK(memtable_lock); + return result; + } + + if ((index = getTable(tspContext)) == NULL) { + MUTEX_UNLOCK(memtable_lock); + /* Tspi_Context_FreeMemory checks that the TSP context is good before calling us, + * so we can be sure that the problem is with memPointer */ + return TSPERR(TSS_E_INVALID_RESOURCE); + } + + /* just free one entry */ + result = __tspi_freeEntry(index, memPointer); + + MUTEX_UNLOCK(memtable_lock); + + return result; +} diff --git a/src/tspi/tsp_counter.c b/src/tspi/tsp_counter.c new file mode 100644 index 0000000..a8d4744 --- /dev/null +++ b/src/tspi/tsp_counter.c @@ -0,0 +1,57 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_ReadCounter(TSS_HCONTEXT tspContext, /* in */ + TSS_COUNTER_ID idCounter, /* in */ + TPM_COUNTER_VALUE* counterValue) /* out */ +{ + TSS_RESULT result; + UINT32 decLen = 0; + BYTE *dec = NULL; + UINT64 offset; + TCS_HANDLE handlesLen = 0; + BYTE data[sizeof(UINT32)]; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, idCounter, data); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_ReadCounter, sizeof(data), + data, NULL, &handlesLen, NULL, NULL, NULL, + &decLen, &dec))) + return result; + + offset = 0; + Trspi_UnloadBlob_COUNTER_VALUE(&offset, dec, counterValue); + + free(dec); + + return TSS_SUCCESS; +} +#endif diff --git a/src/tspi/tsp_daa.c b/src/tspi/tsp_daa.c new file mode 100644 index 0000000..5afbf96 --- /dev/null +++ b/src/tspi/tsp_daa.c @@ -0,0 +1,207 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2006 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "tcs_tsp.h" +#include "tspps.h" + + +void +Trspi_LoadBlob_DAA_PK(UINT64 *offset, BYTE *blob, TSS_DAA_PK *pk) +{ + UINT32 i; + + Trspi_LoadBlob_TSS_VERSION(offset, blob, pk->versionInfo); + + Trspi_LoadBlob_UINT32(offset, pk->modulusLength, blob); + Trspi_LoadBlob(offset, pk->modulusLength, blob, pk->modulus); + + Trspi_LoadBlob_UINT32(offset, pk->capitalSLength, blob); + Trspi_LoadBlob(offset, pk->capitalSLength, blob, pk->capitalS); + + Trspi_LoadBlob_UINT32(offset, pk->capitalZLength, blob); + Trspi_LoadBlob(offset, pk->capitalZLength, blob, pk->capitalZ); + + Trspi_LoadBlob_UINT32(offset, pk->capitalR0Length, blob); + Trspi_LoadBlob(offset, pk->capitalR0Length, blob, pk->capitalR0); + + Trspi_LoadBlob_UINT32(offset, pk->capitalR1Length, blob); + Trspi_LoadBlob(offset, pk->capitalR1Length, blob, pk->capitalR1); + + Trspi_LoadBlob_UINT32(offset, pk->gammaLength, blob); + Trspi_LoadBlob(offset, pk->gammaLength, blob, pk->gamma); + + Trspi_LoadBlob_UINT32(offset, pk->capitalGammaLength, blob); + Trspi_LoadBlob(offset, pk->capitalGammaLength, blob, pk->capitalGamma); + + Trspi_LoadBlob_UINT32(offset, pk->rhoLength, blob); + Trspi_LoadBlob(offset, pk->rhoLength, blob, pk->rho); + + for (i = 0; i < pk->capitalYLength; i++) + Trspi_LoadBlob(offset, pk->capitalYLength2, blob, pk->capitalY[i]); + + Trspi_LoadBlob_UINT32(offset, pk->capitalYPlatformLength, blob); + + Trspi_LoadBlob_UINT32(offset, pk->issuerBaseNameLength, blob); + Trspi_LoadBlob(offset, pk->issuerBaseNameLength, blob, pk->issuerBaseName); +} + +TSS_RESULT +Trspi_UnloadBlob_DAA_PK(UINT64 *offset, BYTE *blob, TSS_DAA_PK *pk) +{ + UINT32 i = 0, j; + + memset(pk, 0, sizeof(TSS_DAA_PK)); + + Trspi_UnloadBlob_TSS_VERSION(offset, blob, &pk->versionInfo); + + Trspi_UnloadBlob_UINT32(offset, &pk->modulusLength, blob); + if (pk->modulusLength > 0) { + if ((pk->modulus = malloc(pk->modulusLength)) == NULL) + return TSPERR(TSS_E_OUTOFMEMORY); + + Trspi_UnloadBlob(offset, pk->modulusLength, blob, pk->modulus); + } else { + pk->modulus = NULL; + } + + Trspi_UnloadBlob_UINT32(offset, &pk->capitalSLength, blob); + if (pk->capitalSLength > 0) { + if ((pk->capitalS = malloc(pk->capitalSLength)) == NULL) + goto error; + + Trspi_UnloadBlob(offset, pk->capitalSLength, blob, pk->capitalS); + } else { + pk->capitalS = NULL; + } + + Trspi_UnloadBlob_UINT32(offset, &pk->capitalZLength, blob); + if (pk->capitalZLength > 0) { + if ((pk->capitalZ = malloc(pk->capitalZLength)) == NULL) + goto error; + + Trspi_UnloadBlob(offset, pk->capitalZLength, blob, pk->capitalZ); + } else { + pk->capitalZ = NULL; + } + + Trspi_UnloadBlob_UINT32(offset, &pk->capitalR0Length, blob); + if (pk->capitalR0Length > 0) { + if ((pk->capitalR0 = malloc(pk->capitalR0Length)) == NULL) + goto error; + + Trspi_UnloadBlob(offset, pk->capitalR0Length, blob, pk->capitalR0); + } else { + pk->capitalR0 = NULL; + } + + Trspi_UnloadBlob_UINT32(offset, &pk->capitalR1Length, blob); + if (pk->capitalR1Length > 0) { + if ((pk->capitalR1 = malloc(pk->capitalR1Length)) == NULL) + goto error; + + Trspi_UnloadBlob(offset, pk->capitalR1Length, blob, pk->capitalR1); + } else { + pk->capitalR1 = NULL; + } + + Trspi_UnloadBlob_UINT32(offset, &pk->gammaLength, blob); + if (pk->gammaLength > 0) { + if ((pk->gamma = malloc(pk->gammaLength)) == NULL) + goto error; + + Trspi_UnloadBlob(offset, pk->gammaLength, blob, pk->gamma); + } else { + pk->gamma = NULL; + } + + Trspi_UnloadBlob_UINT32(offset, &pk->capitalGammaLength, blob); + if (pk->capitalGammaLength > 0) { + if ((pk->capitalGamma = malloc(pk->capitalGammaLength)) == NULL) + goto error; + + Trspi_UnloadBlob(offset, pk->capitalGammaLength, blob, pk->capitalGamma); + } else { + pk->capitalGamma = NULL; + } + + Trspi_UnloadBlob_UINT32(offset, &pk->rhoLength, blob); + if (pk->rhoLength > 0) { + if ((pk->rho = malloc(pk->rhoLength)) == NULL) + goto error; + + Trspi_UnloadBlob(offset, pk->rhoLength, blob, pk->rho); + } else { + pk->rho = NULL; + } + + Trspi_UnloadBlob_UINT32(offset, &pk->capitalYLength, blob); + Trspi_UnloadBlob_UINT32(offset, &pk->capitalYLength2, blob); + + if (pk->capitalYLength > 0 && pk->capitalYLength2 > 0) { + if ((pk->capitalY = calloc(pk->capitalYLength, sizeof(BYTE *))) == NULL) + goto error; + + for (i = 0; i < pk->capitalYLength; i++) { + if ((pk->capitalY[i] = malloc(pk->capitalYLength2)) == NULL) + goto error; + + Trspi_UnloadBlob(offset, pk->capitalYLength2, blob, pk->capitalY[i]); + } + } else { + pk->capitalY = NULL; + } + + Trspi_UnloadBlob_UINT32(offset, &pk->capitalYPlatformLength, blob); + + Trspi_UnloadBlob_UINT32(offset, &pk->issuerBaseNameLength, blob); + if (pk->issuerBaseNameLength > 0) { + if ((pk->issuerBaseName = malloc(pk->issuerBaseNameLength)) == NULL) + goto error; + + Trspi_UnloadBlob(offset, pk->issuerBaseNameLength, blob, pk->issuerBaseName); + } else { + pk->issuerBaseName = NULL; + } + + return TSS_SUCCESS; + +error: + free(pk->modulus); + free(pk->capitalS); + free(pk->capitalZ); + free(pk->capitalR0); + free(pk->capitalR1); + free(pk->gamma); + free(pk->capitalGamma); + free(pk->rho); + if (pk->capitalY) { + for (j = 0; j < i; j++) + free(pk->capitalY[j]); + + free(pk->capitalY); + } + free(pk->issuerBaseName); + + memset(pk, 0, sizeof(TSS_DAA_PK)); + + return TSPERR(TSS_E_OUTOFMEMORY); +} diff --git a/src/tspi/tsp_delegate.c b/src/tspi/tsp_delegate.c new file mode 100644 index 0000000..0319e58 --- /dev/null +++ b/src/tspi/tsp_delegate.c @@ -0,0 +1,865 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "obj.h" +#include "tsplog.h" +#include "tsp_delegate.h" +#include "authsess.h" + + +TSS_RESULT +do_delegate_manage(TSS_HTPM hTpm, UINT32 familyID, UINT32 opFlag, + UINT32 opDataSize, BYTE *opData, UINT32 *outDataSize, BYTE **outData) +{ + TSS_HCONTEXT hContext; + TSS_HPOLICY hPolicy; + UINT32 secretMode = TSS_SECRET_MODE_NONE; + Trspi_HashCtx hashCtx; + TCPA_DIGEST digest; + TPM_AUTH ownerAuth, *pAuth; + UINT32 retDataSize; + BYTE *retData = NULL; + TSS_RESULT result; + + if ((result = obj_tpm_get_tsp_context(hTpm, &hContext))) + return result; + + if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy))) + return result; + + if (hPolicy != NULL_HPOLICY) { + if ((result = obj_policy_get_mode(hPolicy, &secretMode))) + return result; + } + + if (secretMode != TSS_SECRET_MODE_NONE) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_Manage); + result |= Trspi_Hash_UINT32(&hashCtx, familyID); + result |= Trspi_Hash_UINT32(&hashCtx, opFlag); + result |= Trspi_Hash_UINT32(&hashCtx, opDataSize); + result |= Trspi_HashUpdate(&hashCtx, opDataSize, opData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + pAuth = &ownerAuth; + if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_Delegate_Manage, hPolicy, FALSE, + &digest, pAuth))) + return result; + } else + pAuth = NULL; + + /* Perform the delegation operation */ + if ((result = TCS_API(hContext)->Delegate_Manage(hContext, familyID, opFlag, opDataSize, + opData, pAuth, &retDataSize, &retData))) + return result; + + if (pAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_Manage); + result |= Trspi_Hash_UINT32(&hashCtx, retDataSize); + result |= Trspi_HashUpdate(&hashCtx, retDataSize, retData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) { + free(retData); + goto done; + } + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth))) { + free(retData); + goto done; + } + } + + *outDataSize = retDataSize; + *outData = retData; + +done: + return result; +} + +TSS_RESULT +create_owner_delegation(TSS_HTPM hTpm, + BYTE bLabel, + UINT32 ulFlags, + TSS_HPCRS hPcrs, + TSS_HDELFAMILY hFamily, + TSS_HPOLICY hDelegation) +{ + TSS_HCONTEXT hContext; + TSS_BOOL incrementCount = FALSE; + UINT32 type; + UINT32 publicInfoSize; + BYTE *publicInfo = NULL; + Trspi_HashCtx hashCtx; + TCPA_DIGEST digest; + UINT32 blobSize; + BYTE *blob = NULL; + TSS_RESULT result; + struct authsess *xsap = NULL; + + if ((result = obj_tpm_get_tsp_context(hTpm, &hContext))) + return result; + + if ((ulFlags & ~TSS_DELEGATE_INCREMENTVERIFICATIONCOUNT) > 0) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (ulFlags & TSS_DELEGATE_INCREMENTVERIFICATIONCOUNT) + incrementCount = TRUE; + + if ((result = obj_policy_get_delegation_type(hDelegation, &type))) + return result; + + if (type != TSS_DELEGATIONTYPE_OWNER) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = __tspi_build_delegate_public_info(bLabel, hPcrs, hFamily, hDelegation, + &publicInfoSize, &publicInfo))) + return result; + + if ((result = authsess_xsap_init(hContext, hTpm, hDelegation, TSS_AUTH_POLICY_NOT_REQUIRED, + TPM_ORD_Delegate_CreateOwnerDelegation, TPM_ET_OWNER, + &xsap))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_CreateOwnerDelegation); + result |= Trspi_Hash_BOOL(&hashCtx, incrementCount); + result |= Trspi_HashUpdate(&hashCtx, publicInfoSize, publicInfo); + result |= Trspi_Hash_DIGEST(&hashCtx, xsap->encAuthUse.authdata); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if ((result = authsess_xsap_hmac(xsap, &digest))) + goto done; + + /* Create the delegation */ + if ((result = TCS_API(hContext)->Delegate_CreateOwnerDelegation(hContext, incrementCount, + publicInfoSize, publicInfo, + &xsap->encAuthUse, + xsap->pAuth, &blobSize, + &blob))) + goto done; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_CreateOwnerDelegation); + result |= Trspi_Hash_UINT32(&hashCtx, blobSize); + result |= Trspi_HashUpdate(&hashCtx, blobSize, blob); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if (authsess_xsap_verify(xsap, &digest)) { + result = TSPERR(TSS_E_TSP_AUTHFAIL); + goto done; + } + + result = obj_policy_set_delegation_blob(hDelegation, TSS_DELEGATIONTYPE_OWNER, + blobSize, blob); + +done: + authsess_free(xsap); + free(publicInfo); + free(blob); + + return result; +} + +TSS_RESULT +create_key_delegation(TSS_HKEY hKey, + BYTE bLabel, + UINT32 ulFlags, + TSS_HPCRS hPcrs, + TSS_HDELFAMILY hFamily, + TSS_HPOLICY hDelegation) +{ + TSS_HCONTEXT hContext; + UINT32 type; + TCS_KEY_HANDLE tcsKeyHandle; + UINT32 publicInfoSize; + BYTE *publicInfo = NULL; + Trspi_HashCtx hashCtx; + TCPA_DIGEST digest; + UINT32 blobSize; + BYTE *blob = NULL; + TSS_RESULT result; + struct authsess *xsap = NULL; + + if ((result = obj_rsakey_get_tsp_context(hKey, &hContext))) + return result; + + if (ulFlags != 0) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_policy_get_delegation_type(hDelegation, &type))) + return result; + + if (type != TSS_DELEGATIONTYPE_KEY) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle))) + return result; + + if ((result = __tspi_build_delegate_public_info(bLabel, hPcrs, hFamily, hDelegation, + &publicInfoSize, &publicInfo))) + return result; + + if ((result = authsess_xsap_init(hContext, hKey, hDelegation, TSS_AUTH_POLICY_REQUIRED, + TPM_ORD_Delegate_CreateKeyDelegation, TPM_ET_KEYHANDLE, + &xsap))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_CreateKeyDelegation); + result |= Trspi_HashUpdate(&hashCtx, publicInfoSize, publicInfo); + result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if ((result = authsess_xsap_hmac(xsap, &digest))) + goto done; + + /* Create the delegation */ + if ((result = TCS_API(hContext)->Delegate_CreateKeyDelegation(hContext, tcsKeyHandle, + publicInfoSize, publicInfo, + &xsap->encAuthUse, + xsap->pAuth, &blobSize, + &blob))) + goto done; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_CreateKeyDelegation); + result |= Trspi_Hash_UINT32(&hashCtx, blobSize); + result |= Trspi_HashUpdate(&hashCtx, blobSize, blob); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if (authsess_xsap_verify(xsap, &digest)) { + result = TSPERR(TSS_E_TSP_AUTHFAIL); + goto done; + } + + result = obj_policy_set_delegation_blob(hDelegation, TSS_DELEGATIONTYPE_KEY, blobSize, + blob); + +done: + free(blob); + authsess_free(xsap); + free(publicInfo); + + return result; +} + +TSS_RESULT +update_delfamily_object(TSS_HTPM hTpm, UINT32 familyID) +{ + TSS_HCONTEXT hContext; + UINT32 familyTableSize, delegateTableSize; + BYTE *familyTable = NULL, *delegateTable = NULL; + UINT64 offset; + TPM_FAMILY_TABLE_ENTRY familyTableEntry; + TSS_BOOL familyState; + TSS_HDELFAMILY hFamily; + TSS_RESULT result; + + if ((result = obj_tpm_get_tsp_context(hTpm, &hContext))) + return result; + + if ((result = TCS_API(hContext)->Delegate_ReadTable(hContext, &familyTableSize, + &familyTable, &delegateTableSize, + &delegateTable))) + return result; + + for (offset = 0; offset < familyTableSize;) { + Trspi_UnloadBlob_TPM_FAMILY_TABLE_ENTRY(&offset, familyTable, &familyTableEntry); + if (familyTableEntry.familyID == familyID) { + obj_delfamily_find_by_familyid(hContext, familyID, &hFamily); + if (hFamily == NULL_HDELFAMILY) { + if ((result = obj_delfamily_add(hContext, &hFamily))) + goto done; + if ((result = obj_delfamily_set_familyid(hFamily, + familyTableEntry.familyID))) + goto done; + if ((result = obj_delfamily_set_label(hFamily, + familyTableEntry.label.label))) + goto done; + } + + /* Set/Update the family attributes */ + familyState = (familyTableEntry.flags & TPM_FAMFLAG_DELEGATE_ADMIN_LOCK) ? + TRUE : FALSE; + if ((result = obj_delfamily_set_locked(hFamily, familyState, FALSE))) + goto done; + familyState = (familyTableEntry.flags & TPM_FAMFLAG_ENABLE) ? TRUE : FALSE; + if ((result = obj_delfamily_set_enabled(hFamily, familyState, FALSE))) + goto done; + if ((result = obj_delfamily_set_vercount(hFamily, + familyTableEntry.verificationCount))) + goto done; + + break; + } + } + +done: + free(familyTable); + free(delegateTable); + + return result; +} + +TSS_RESULT +get_delegate_index(TSS_HCONTEXT hContext, UINT32 index, TPM_DELEGATE_PUBLIC *public) +{ + UINT32 familyTableSize, delegateTableSize; + BYTE *familyTable = NULL, *delegateTable = NULL; + UINT64 offset; + UINT32 tpmIndex; + TPM_DELEGATE_PUBLIC tempPublic; + TSS_RESULT result; + + if ((result = TCS_API(hContext)->Delegate_ReadTable(hContext, &familyTableSize, + &familyTable, &delegateTableSize, + &delegateTable))) + goto done; + + for (offset = 0; offset < delegateTableSize;) { + Trspi_UnloadBlob_UINT32(&offset, &tpmIndex, delegateTable); + if (tpmIndex == index) { + result = Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC(&offset, delegateTable, public); + goto done; + } else { + if ((result = Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC(&offset, delegateTable, &tempPublic))) + goto done; + } + + free(tempPublic.pcrInfo.pcrSelection.pcrSelect); + } + + /* Didn't find a matching index */ + result = TSPERR(TSS_E_BAD_PARAMETER); + +done: + free(familyTable); + free(delegateTable); + + return result; +} + +TSS_RESULT +__tspi_build_delegate_public_info(BYTE bLabel, + TSS_HPCRS hPcrs, + TSS_HDELFAMILY hFamily, + TSS_HPOLICY hDelegation, + UINT32 *publicInfoSize, + BYTE **publicInfo) +{ + TPM_DELEGATE_PUBLIC public; + UINT32 delegateType; + UINT32 pcrInfoSize; + BYTE *pcrInfo = NULL; + UINT64 offset; + TSS_RESULT result = TSS_SUCCESS; + + if (hDelegation == NULL_HPOLICY) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_policy_get_delegation_type(hDelegation, &delegateType))) + return result; + + /* This call will create a "null" PCR_INFO_SHORT if hPcrs is null */ + if ((result = obj_pcrs_create_info_short(hPcrs, &pcrInfoSize, &pcrInfo))) + return result; + + memset(&public, 0, sizeof(public)); + public.tag = TPM_TAG_DELEGATE_PUBLIC; + public.label.label = bLabel; + offset = 0; + if ((result = Trspi_UnloadBlob_PCR_INFO_SHORT(&offset, pcrInfo, &public.pcrInfo))) + goto done; + public.permissions.tag = TPM_TAG_DELEGATIONS; + public.permissions.delegateType = + (delegateType == TSS_DELEGATIONTYPE_OWNER) ? TPM_DEL_OWNER_BITS : TPM_DEL_KEY_BITS; + if ((result = obj_policy_get_delegation_per1(hDelegation, &public.permissions.per1))) + goto done; + if ((result = obj_policy_get_delegation_per2(hDelegation, &public.permissions.per2))) + goto done; + if ((result = obj_delfamily_get_familyid(hFamily, &public.familyID))) + goto done; + if ((result = obj_delfamily_get_vercount(hFamily, &public.verificationCount))) + goto done; + + offset = 0; + Trspi_LoadBlob_TPM_DELEGATE_PUBLIC(&offset, NULL, &public); + *publicInfoSize = offset; + *publicInfo = malloc(*publicInfoSize); + if (*publicInfo == NULL) { + LogError("malloc of %u bytes failed.", *publicInfoSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + offset = 0; + Trspi_LoadBlob_TPM_DELEGATE_PUBLIC(&offset, *publicInfo, &public); + +done: + free(pcrInfo); + free(public.pcrInfo.pcrSelection.pcrSelect); + + return result; +} + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_Delegate_Manage(TSS_HCONTEXT tspContext, /* in */ + TPM_FAMILY_ID familyID, /* in */ + TPM_FAMILY_OPERATION opFlag, /* in */ + UINT32 opDataSize, /* in */ + BYTE *opData, /* in */ + TPM_AUTH *ownerAuth, /* in, out */ + UINT32 *retDataSize, /* out */ + BYTE **retData) /* out */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0, decLen, dataLen; + UINT64 offset; + BYTE *data, *dec = NULL; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + dataLen = sizeof(TPM_FAMILY_ID) + + sizeof(TPM_FAMILY_OPERATION) + + sizeof(UINT32) + + opDataSize; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, familyID, data); + Trspi_LoadBlob_UINT32(&offset, opFlag, data); + Trspi_LoadBlob_UINT32(&offset, opDataSize, data); + Trspi_LoadBlob(&offset, opDataSize, data, opData); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Delegate_Manage, dataLen, + data, NULL, &handlesLen, NULL, ownerAuth, + NULL, &decLen, &dec))) { + free(data); + return result; + } + free(data); + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, retDataSize, dec); + + if ((*retData = malloc(*retDataSize)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *retDataSize); + *retDataSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *retDataSize, dec, *retData); + + free(dec); + + return result; +} + +TSS_RESULT +Transport_Delegate_CreateKeyDelegation(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE hKey, /* in */ + UINT32 publicInfoSize, /* in */ + BYTE *publicInfo, /* in */ + TPM_ENCAUTH *encDelAuth, /* in */ + TPM_AUTH *keyAuth, /* in, out */ + UINT32 *blobSize, /* out */ + BYTE **blob) /* out */ +{ + TSS_RESULT result; + UINT32 handlesLen, decLen, dataLen; + TCS_HANDLE *handles, handle; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + UINT64 offset; + BYTE *data, *dec = NULL; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + handlesLen = 1; + handle = hKey; + handles = &handle; + + dataLen = publicInfoSize + sizeof(TPM_ENCAUTH); + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob(&offset, publicInfoSize, data, publicInfo); + Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, encDelAuth->authdata); + + if ((result = obj_context_transport_execute(tspContext, + TPM_ORD_Delegate_CreateKeyDelegation, dataLen, + data, &pubKeyHash, &handlesLen, &handles, + keyAuth, NULL, &decLen, &dec))) { + free(data); + return result; + } + free(data); + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, blobSize, dec); + + if ((*blob = malloc(*blobSize)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *blobSize); + *blobSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *blobSize, dec, *blob); + + free(dec); + + return result; +} + +TSS_RESULT +Transport_Delegate_CreateOwnerDelegation(TSS_HCONTEXT tspContext, /* in */ + TSS_BOOL increment, /* in */ + UINT32 publicInfoSize, /* in */ + BYTE *publicInfo, /* in */ + TPM_ENCAUTH *encDelAuth, /* in */ + TPM_AUTH *ownerAuth, /* in, out */ + UINT32 *blobSize, /* out */ + BYTE **blob) /* out */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0, decLen, dataLen; + UINT64 offset; + BYTE *data, *dec = NULL; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + dataLen = sizeof(TSS_BOOL) + publicInfoSize + sizeof(TPM_ENCAUTH); + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob_BOOL(&offset, increment, data); + Trspi_LoadBlob(&offset, publicInfoSize, data, publicInfo); + Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, encDelAuth->authdata); + + if ((result = obj_context_transport_execute(tspContext, + TPM_ORD_Delegate_CreateOwnerDelegation, dataLen, + data, NULL, &handlesLen, NULL, ownerAuth, + NULL, &decLen, &dec))) { + free(data); + return result; + } + free(data); + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, blobSize, dec); + + if ((*blob = malloc(*blobSize)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *blobSize); + *blobSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *blobSize, dec, *blob); + + free(dec); + + return result; +} + +TSS_RESULT +Transport_Delegate_LoadOwnerDelegation(TSS_HCONTEXT tspContext, /* in */ + TPM_DELEGATE_INDEX index, /* in */ + UINT32 blobSize, /* in */ + BYTE *blob, /* in */ + TPM_AUTH *ownerAuth) /* in, out */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0, dataLen, decLen; + UINT64 offset; + BYTE *data, *dec = NULL; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + dataLen = sizeof(TPM_DELEGATE_INDEX) + sizeof(UINT32) + blobSize; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, index, data); + Trspi_LoadBlob_UINT32(&offset, blobSize, data); + Trspi_LoadBlob(&offset, blobSize, data, blob); + + if ((result = obj_context_transport_execute(tspContext, + TPM_ORD_Delegate_LoadOwnerDelegation, dataLen, + data, NULL, &handlesLen, NULL, ownerAuth, + NULL, &decLen, &dec))) { + free(data); + return result; + } + free(data); + free(dec); + + return result; +} + +TSS_RESULT +Transport_Delegate_ReadTable(TSS_HCONTEXT tspContext, /* in */ + UINT32 *familyTableSize, /* out */ + BYTE **familyTable, /* out */ + UINT32 *delegateTableSize, /* out */ + BYTE **delegateTable) /* out */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0, decLen; + UINT64 offset; + BYTE *dec = NULL; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Delegate_ReadTable, 0, NULL, + NULL, &handlesLen, NULL, NULL, NULL, &decLen, + &dec))) + return result; + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, familyTableSize, dec); + + if ((*familyTable = malloc(*familyTableSize)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *familyTableSize); + *familyTableSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *familyTableSize, dec, *familyTable); + + Trspi_UnloadBlob_UINT32(&offset, delegateTableSize, dec); + + if ((*delegateTable = malloc(*delegateTableSize)) == NULL) { + free(dec); + free(*familyTable); + *familyTable = NULL; + *familyTableSize = 0; + LogError("malloc of %u bytes failed", *delegateTableSize); + *delegateTableSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *delegateTableSize, dec, *delegateTable); + + free(dec); + + return result; +} + +TSS_RESULT +Transport_Delegate_UpdateVerificationCount(TSS_HCONTEXT tspContext, /* in */ + UINT32 inputSize, /* in */ + BYTE *input, /* in */ + TPM_AUTH *ownerAuth, /* in, out */ + UINT32 *outputSize, /* out */ + BYTE **output) /* out */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0, decLen, dataLen; + UINT64 offset; + BYTE *data, *dec = NULL; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + dataLen = sizeof(UINT32) + inputSize; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, inputSize, data); + Trspi_LoadBlob(&offset, inputSize, data, input); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Delegate_UpdateVerification, + dataLen, data, NULL, &handlesLen, NULL, + ownerAuth, NULL, &decLen, &dec))) { + free(data); + return result; + } + free(data); + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, outputSize, dec); + + if ((*output = malloc(*outputSize)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *outputSize); + *outputSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *outputSize, dec, *output); + + free(dec); + + return result; +} + +TSS_RESULT +Transport_Delegate_VerifyDelegation(TSS_HCONTEXT tspContext, /* in */ + UINT32 delegateSize, /* in */ + BYTE *delegate) /* in */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0, dataLen, decLen; + UINT64 offset; + BYTE *data, *dec = NULL; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + dataLen = + sizeof(UINT32) + delegateSize; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, delegateSize, data); + Trspi_LoadBlob(&offset, delegateSize, data, delegate); + + result = obj_context_transport_execute(tspContext, TPM_ORD_Delegate_VerifyDelegation, + dataLen, data, NULL, &handlesLen, NULL, NULL, NULL, + &decLen, &dec); + free(data); + free(dec); + + return result; +} + +TSS_RESULT +Transport_DSAP(TSS_HCONTEXT tspContext, /* in */ + TPM_ENTITY_TYPE entityType, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + TPM_NONCE *nonceOddDSAP, /* in */ + UINT32 entityValueSize, /* in */ + BYTE * entityValue, /* in */ + TCS_AUTHHANDLE *authHandle, /* out */ + TPM_NONCE *nonceEven, /* out */ + TPM_NONCE *nonceEvenDSAP) /* out */ +{ + TSS_RESULT result; + UINT32 handlesLen, dataLen, decLen; + TCS_HANDLE *handles, handle; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + UINT64 offset; + BYTE *data, *dec = NULL; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + dataLen = sizeof(TPM_ENTITY_TYPE) + sizeof(TPM_KEY_HANDLE) + + sizeof(TPM_NONCE) + + sizeof(UINT32) + + entityValueSize; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + handlesLen = 1; + handle = keyHandle; + handles = &handle; + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, entityType, data); + Trspi_LoadBlob_UINT32(&offset, keyHandle, data); + Trspi_LoadBlob(&offset, sizeof(TPM_NONCE), data, nonceEvenDSAP->nonce); + Trspi_LoadBlob_UINT32(&offset, entityValueSize, data); + Trspi_LoadBlob(&offset, entityValueSize, data, entityValue); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_DSAP, dataLen, data, + &pubKeyHash, &handlesLen, &handles, NULL, NULL, + &decLen, &dec))) { + free(data); + return result; + } + free(data); + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, authHandle, dec); + + Trspi_UnloadBlob(&offset, sizeof(TPM_NONCE), dec, nonceEven->nonce); + Trspi_UnloadBlob(&offset, sizeof(TPM_NONCE), dec, nonceEvenDSAP->nonce); + + free(dec); + + return result; +} +#endif diff --git a/src/tspi/tsp_dir.c b/src/tspi/tsp_dir.c new file mode 100644 index 0000000..9e5bb94 --- /dev/null +++ b/src/tspi/tsp_dir.c @@ -0,0 +1,83 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + + +#include <stdlib.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_DirWriteAuth(TSS_HCONTEXT tspContext, /* in */ + TCPA_DIRINDEX dirIndex, /* in */ + TCPA_DIRVALUE *newContents, /* in */ + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0; + UINT64 offset; + BYTE data[sizeof(TCPA_DIRINDEX) + sizeof(TCPA_DIRVALUE)]; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, dirIndex, data); + Trspi_LoadBlob_DIGEST(&offset, data, (TPM_DIGEST *)newContents); + + result = obj_context_transport_execute(tspContext, TPM_ORD_DirWriteAuth, sizeof(data), data, + NULL, &handlesLen, NULL, ownerAuth, NULL, NULL, + NULL); + + return result; +} + +TSS_RESULT +Transport_DirRead(TSS_HCONTEXT tspContext, /* in */ + TCPA_DIRINDEX dirIndex, /* in */ + TCPA_DIRVALUE * dirValue) /* out */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0, decLen; + UINT64 offset; + BYTE data[sizeof(TCPA_DIRINDEX)], *dec; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, dirIndex, data); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_DirRead, sizeof(data), data, + NULL, &handlesLen, NULL, NULL, NULL, &decLen, + &dec))) + return result; + + offset = 0; + Trspi_UnloadBlob_DIGEST(&offset, dec, dirValue); + + return result; +} +#endif + diff --git a/src/tspi/tsp_ek.c b/src/tspi/tsp_ek.c new file mode 100644 index 0000000..4c2ae4f --- /dev/null +++ b/src/tspi/tsp_ek.c @@ -0,0 +1,108 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +owner_get_pubek(TSS_HCONTEXT tspContext, TSS_HTPM hTPM, TSS_HKEY *hPubEk) +{ + TSS_RESULT result; + UINT32 tpmVersion, pubEKSize; + TSS_HPOLICY hPolicy; + Trspi_HashCtx hashCtx; + BYTE *pubEK = NULL; + TSS_HKEY hRetKey; + TPM_AUTH ownerAuth; + TPM_DIGEST digest; + + + if ((result = obj_context_get_tpm_version(tspContext, &tpmVersion))) + return result; + + if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy))) + return result; + + switch (tpmVersion) { + case 2: + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerReadInternalPub); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_KH_EK); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_OwnerReadInternalPub, + hPolicy, FALSE, &digest, &ownerAuth))) + goto done; + + if ((result = TCS_API(tspContext)->OwnerReadInternalPub(tspContext, TPM_KH_EK, + &ownerAuth, &pubEKSize, + &pubEK))) + goto done; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerReadInternalPub); + result |= Trspi_HashUpdate(&hashCtx, pubEKSize, pubEK); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth))) + goto done; + break; + default: + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerReadPubek); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_OwnerReadPubek, hPolicy, FALSE, + &digest, &ownerAuth))) + goto done; + + if ((result = TCS_API(tspContext)->OwnerReadPubek(tspContext, &ownerAuth, + &pubEKSize, &pubEK))) + goto done; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerReadPubek); + result |= Trspi_HashUpdate(&hashCtx, pubEKSize, pubEK); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth))) + goto done; + + break; + } + + if ((result = obj_rsakey_add(tspContext, TSS_KEY_SIZE_2048|TSS_KEY_TYPE_LEGACY, &hRetKey))) + goto done; + + if ((result = obj_rsakey_set_pubkey(hRetKey, TRUE, pubEK))) + goto done; + + *hPubEk = hRetKey; +done: + free(pubEK); + return result; +} diff --git a/src/tspi/tsp_get_flags.c b/src/tspi/tsp_get_flags.c new file mode 100644 index 0000000..f974052 --- /dev/null +++ b/src/tspi/tsp_get_flags.c @@ -0,0 +1,67 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <errno.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +get_tpm_flags(TSS_HCONTEXT tspContext, TSS_HTPM hTPM, UINT32 *volFlags, UINT32 *nonVolFlags) +{ + TCPA_DIGEST digest; + TPM_AUTH auth; + TCPA_VERSION version; + TSS_RESULT result; + TSS_HPOLICY hPolicy; + Trspi_HashCtx hashCtx; + + if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy))) + return result; + + /* do an owner authorized get capability call */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_GetCapabilityOwner); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_GetCapabilityOwner, hPolicy, FALSE, + &digest, &auth))) + return result; + + if ((result = TCS_API(tspContext)->GetCapabilityOwner(tspContext, &auth, &version, + nonVolFlags, volFlags))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_GetCapabilityOwner); + result |= Trspi_Hash_VERSION(&hashCtx, (TSS_VERSION *)&version); + result |= Trspi_Hash_UINT32(&hashCtx, *nonVolFlags); + result |= Trspi_Hash_UINT32(&hashCtx, *volFlags); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + return obj_policy_validate_auth_oiap(hPolicy, &digest, &auth); +} diff --git a/src/tspi/tsp_key.c b/src/tspi/tsp_key.c new file mode 100644 index 0000000..d882527 --- /dev/null +++ b/src/tspi/tsp_key.c @@ -0,0 +1,337 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + + +#include <stdlib.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +void +free_key_refs(TSS_KEY *key) +{ + free(key->algorithmParms.parms); + key->algorithmParms.parms = NULL; + key->algorithmParms.parmSize = 0; + + free(key->pubKey.key); + key->pubKey.key = NULL; + key->pubKey.keyLength = 0; + + free(key->encData); + key->encData = NULL; + key->encSize = 0; + + free(key->PCRInfo); + key->PCRInfo = NULL; + key->PCRInfoSize = 0; +} + +void +LoadBlob_TSS_KEY(UINT64 *offset, BYTE *blob, TSS_KEY *key) +{ + if (key->hdr.key12.tag == TPM_TAG_KEY12) + Trspi_LoadBlob_KEY12(offset, blob, (TPM_KEY12 *)key); + else + Trspi_LoadBlob_KEY(offset, blob, (TCPA_KEY *)key); +} + +TSS_RESULT +UnloadBlob_TSS_KEY(UINT64 *offset, BYTE *blob, TSS_KEY *key) +{ + UINT16 tag; + UINT64 keyOffset = *offset; + TSS_RESULT result; + + Trspi_UnloadBlob_UINT16(&keyOffset, &tag, blob); + if (tag == TPM_TAG_KEY12) + result = Trspi_UnloadBlob_KEY12(offset, blob, (TPM_KEY12 *)key); + else + result = Trspi_UnloadBlob_KEY(offset, blob, (TCPA_KEY *)key); + + return result; +} + +TSS_RESULT +Hash_TSS_KEY(Trspi_HashCtx *c, TSS_KEY *key) +{ + TSS_RESULT result; + + if (key->hdr.key12.tag == TPM_TAG_KEY12) + result = Trspi_Hash_KEY12(c, (TPM_KEY12 *)key); + else + result = Trspi_Hash_KEY(c, (TCPA_KEY *)key); + + return result; +} + +void +LoadBlob_TSS_PRIVKEY_DIGEST(UINT64 *offset, BYTE *blob, TSS_KEY *key) +{ + if (key->hdr.key12.tag == TPM_TAG_KEY12) + Trspi_LoadBlob_PRIVKEY_DIGEST12(offset, blob, (TPM_KEY12 *)key); + else + Trspi_LoadBlob_PRIVKEY_DIGEST(offset, blob, (TCPA_KEY *)key); +} + +TSS_RESULT +Hash_TSS_PRIVKEY_DIGEST(Trspi_HashCtx *c, TSS_KEY *key) +{ + TSS_RESULT result; + + if (key->hdr.key12.tag == TPM_TAG_KEY12) + result = Trspi_Hash_PRIVKEY_DIGEST12(c, (TPM_KEY12 *)key); + else + result = Trspi_Hash_PRIVKEY_DIGEST(c, (TCPA_KEY *)key); + + return result; +} + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_EvictKey(TSS_HCONTEXT tspContext, + TCS_KEY_HANDLE hKey) +{ + TSS_RESULT result; + UINT32 handlesLen; + TCS_HANDLE *handles, handle; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + handlesLen = 1; + handle = hKey; + handles = &handle; + + result = obj_context_transport_execute(tspContext, TPM_ORD_EvictKey, 0, NULL, &pubKeyHash, + &handlesLen, &handles, NULL, NULL, NULL, NULL); + + return result; +} + +TSS_RESULT +Transport_GetPubKey(TSS_HCONTEXT tspContext, + TCS_KEY_HANDLE hKey, + TPM_AUTH *pAuth, + UINT32 *pcPubKeySize, + BYTE **prgbPubKey) +{ + TSS_RESULT result; + UINT32 handlesLen, decLen; + TCS_HANDLE *handles, handle; + BYTE *dec = NULL; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + handlesLen = 1; + handle = hKey; + handles = &handle; + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetPubKey, 0, NULL, + &pubKeyHash, &handlesLen, &handles, pAuth, NULL, + &decLen, &dec))) + return result; + + *prgbPubKey = dec; + *pcPubKeySize = decLen; + + return result; +} + +TSS_RESULT +Transport_CreateWrapKey(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE hWrappingKey, /* in */ + TPM_ENCAUTH *KeyUsageAuth, /* in */ + TPM_ENCAUTH *KeyMigrationAuth, /* in */ + UINT32 keyInfoSize, /* in */ + BYTE * keyInfo, /* in */ + UINT32 * keyDataSize, /* out */ + BYTE ** keyData, /* out */ + TPM_AUTH * pAuth) /* in, out */ +{ + TSS_RESULT result; + UINT32 handlesLen, decLen; + TCS_HANDLE *handles, handle; + BYTE *dec = NULL; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + UINT64 offset; + BYTE *data; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(hWrappingKey, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + handlesLen = 1; + handle = hWrappingKey; + handles = &handle; + + if ((data = malloc(2 * sizeof(TPM_ENCAUTH) + keyInfoSize)) == NULL) { + LogError("malloc of %zd bytes failed", 2 * sizeof(TPM_ENCAUTH) + keyInfoSize); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, KeyUsageAuth->authdata); + Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, KeyMigrationAuth->authdata); + Trspi_LoadBlob(&offset, keyInfoSize, data, keyInfo); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_CreateWrapKey, + (2 * sizeof(TPM_ENCAUTH) + keyInfoSize), data, + &pubKeyHash, &handlesLen, &handles, pAuth, NULL, + &decLen, &dec))) + goto done; + + *keyDataSize = decLen; + *keyData = dec; +done: + free(data); + + return result; +} + +TSS_RESULT +Transport_LoadKeyByBlob(TSS_HCONTEXT tspContext, + TCS_KEY_HANDLE hParentKey, + UINT32 ulBlobLength, + BYTE* rgbBlobData, + TPM_AUTH* pAuth, + TCS_KEY_HANDLE* phKey, + TPM_KEY_HANDLE* phSlot) +{ + TSS_RESULT result; + UINT32 handlesLen, decLen; + TCS_HANDLE *handles, handle; + BYTE *dec = NULL; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(hParentKey, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + handlesLen = 1; + handle = hParentKey; + handles = &handle; + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_LoadKey2, ulBlobLength, + rgbBlobData, &pubKeyHash, &handlesLen, + &handles, pAuth, NULL, &decLen, &dec))) + return result; + + if (handlesLen == 1) + *phKey = *(TCS_KEY_HANDLE *)handles; + else + result = TSPERR(TSS_E_INTERNAL_ERROR); + + free(dec); + + return result; +} + +/* This function both encrypts the handle of the pubkey being requested and requires the hash + * of that pubkey for the transport log when logging is enabled. */ +TSS_RESULT +Transport_OwnerReadInternalPub(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE hKey, /* in */ + TPM_AUTH* pOwnerAuth, /* in, out */ + UINT32* punPubKeySize, /* out */ + BYTE** ppbPubKeyData) /* out */ +{ + UINT64 offset; + TSS_RESULT result; + UINT32 handlesLen = 0, decLen; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + BYTE *dec = NULL, data[sizeof(TCS_KEY_HANDLE)]; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, hKey, data); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_OwnerReadInternalPub, + sizeof(data), data, &pubKeyHash, &handlesLen, + NULL, pOwnerAuth, NULL, &decLen, &dec))) + return result; + + *punPubKeySize = decLen; + *ppbPubKeyData = dec; + + return result; +} +#endif + diff --git a/src/tspi/tsp_maint.c b/src/tspi/tsp_maint.c new file mode 100644 index 0000000..3e50ddd --- /dev/null +++ b/src/tspi/tsp_maint.c @@ -0,0 +1,197 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_CreateMaintenanceArchive(TSS_HCONTEXT tspContext, /* in */ + TSS_BOOL generateRandom, /* in */ + TPM_AUTH * ownerAuth, /* in, out */ + UINT32 * randomSize, /* out */ + BYTE ** random, /* out */ + UINT32 * archiveSize, /* out */ + BYTE ** archive) /* out */ +{ + UINT64 offset; + TSS_RESULT result; + UINT32 handlesLen = 0, decLen; + BYTE *dec; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_CreateMaintenanceArchive, + sizeof(TSS_BOOL), (BYTE *)&generateRandom, NULL, + &handlesLen, NULL, ownerAuth, NULL, &decLen, + &dec))) + return result; + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, randomSize, dec); + if (*randomSize > 0) { + if ((*random = malloc(*randomSize)) == NULL) { + *randomSize = 0; + free(dec); + LogError("malloc of %u bytes failed", *randomSize); + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *randomSize, dec, *random); + } + + Trspi_UnloadBlob_UINT32(&offset, archiveSize, dec); + if ((*archive = malloc(*archiveSize)) == NULL) { + free(*random); + *random = NULL; + *randomSize = 0; + free(dec); + LogError("malloc of %u bytes failed", *archiveSize); + *archiveSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *archiveSize, dec, *archive); + free(dec); + + return result; +} + +TSS_RESULT +Transport_LoadMaintenanceArchive(TSS_HCONTEXT tspContext, /* in */ + UINT32 dataInSize, /* in */ + BYTE * dataIn, /* in */ + TPM_AUTH * ownerAuth, /* in, out */ + UINT32 * dataOutSize, /* out */ + BYTE ** dataOut) /* out */ +{ + UINT64 offset; + TSS_RESULT result; + UINT32 handlesLen = 0, decLen; + BYTE *dec; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_LoadMaintenanceArchive, + dataInSize, dataIn, NULL, &handlesLen, NULL, + ownerAuth, NULL, &decLen, &dec))) + return result; + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, dataOutSize, dec); + + /* sacrifice 4 bytes */ + *dataOut = &dec[offset]; + + return result; +} + +TSS_RESULT +Transport_KillMaintenanceFeature(TSS_HCONTEXT tspContext, /* in */ + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + return obj_context_transport_execute(tspContext, TPM_ORD_KillMaintenanceFeature, 0, NULL, + NULL, &handlesLen, NULL, ownerAuth, NULL, NULL, NULL); +} + +TSS_RESULT +Transport_LoadManuMaintPub(TSS_HCONTEXT tspContext, /* in */ + TCPA_NONCE antiReplay, /* in */ + UINT32 PubKeySize, /* in */ + BYTE * PubKey, /* in */ + TCPA_DIGEST * checksum) /* out */ +{ + UINT64 offset; + TSS_RESULT result; + UINT32 handlesLen = 0, dataLen, decLen; + BYTE *data, *dec; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + dataLen = sizeof(TCPA_NONCE) + PubKeySize; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob(&offset, TPM_SHA1_160_HASH_LEN, data, antiReplay.nonce); + Trspi_LoadBlob(&offset, PubKeySize, data, PubKey); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_LoadManuMaintPub, + dataLen, data, NULL, &handlesLen, NULL, NULL, + NULL, &decLen, &dec))) { + free(data); + return result; + } + free(data); + + offset = 0; + Trspi_UnloadBlob_DIGEST(&offset, dec, checksum); + free(dec); + + return result; +} + +TSS_RESULT +Transport_ReadManuMaintPub(TSS_HCONTEXT tspContext, /* in */ + TCPA_NONCE antiReplay, /* in */ + TCPA_DIGEST * checksum) /* out */ +{ + UINT64 offset; + TSS_RESULT result; + UINT32 handlesLen = 0, decLen; + BYTE *dec; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_ReadManuMaintPub, + sizeof(TCPA_NONCE), antiReplay.nonce, NULL, + &handlesLen, NULL, NULL, NULL, &decLen, + &dec))) + return result; + + offset = 0; + Trspi_UnloadBlob_DIGEST(&offset, dec, checksum); + free(dec); + + return result; +} +#endif + diff --git a/src/tspi/tsp_migration.c b/src/tspi/tsp_migration.c new file mode 100644 index 0000000..9c83753 --- /dev/null +++ b/src/tspi/tsp_migration.c @@ -0,0 +1,263 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_CreateMigrationBlob(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE parentHandle, /* in */ + TCPA_MIGRATE_SCHEME migrationType, /* in */ + UINT32 MigrationKeyAuthSize, /* in */ + BYTE * MigrationKeyAuth, /* in */ + UINT32 encDataSize, /* in */ + BYTE * encData, /* in */ + TPM_AUTH * parentAuth, /* in, out */ + TPM_AUTH * entityAuth, /* in, out */ + UINT32 * randomSize, /* out */ + BYTE ** random, /* out */ + UINT32 * outDataSize, /* out */ + BYTE ** outData) /* out */ +{ + UINT64 offset; + TSS_RESULT result; + UINT32 handlesLen, dataLen, decLen; + TCS_HANDLE *handles, handle; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + BYTE *data, *dec; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(parentHandle, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + handlesLen = 1; + handle = parentHandle; + handles = &handle; + + dataLen = sizeof(TCPA_MIGRATE_SCHEME) + + MigrationKeyAuthSize + + sizeof(UINT32) + + encDataSize; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob_UINT16(&offset, migrationType, data); + Trspi_LoadBlob(&offset, MigrationKeyAuthSize, data, MigrationKeyAuth); + Trspi_LoadBlob_UINT32(&offset, encDataSize, data); + Trspi_LoadBlob(&offset, encDataSize, data, encData); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_CreateMigrationBlob, + dataLen, data, &pubKeyHash, &handlesLen, + &handles, parentAuth, entityAuth, &decLen, + &dec))) { + free(data); + return result; + } + free(data); + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, randomSize, dec); + + if ((*random = malloc(*randomSize)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *randomSize); + *randomSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *randomSize, dec, *random); + + Trspi_UnloadBlob_UINT32(&offset, outDataSize, dec); + + if ((*outData = malloc(*outDataSize)) == NULL) { + free(*random); + *random = NULL; + *randomSize = 0; + free(dec); + LogError("malloc of %u bytes failed", *outDataSize); + *outDataSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *outDataSize, dec, *outData); + free(dec); + + return result; +} + +TSS_RESULT +Transport_ConvertMigrationBlob(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE parentHandle, /* in */ + UINT32 inDataSize, /* in */ + BYTE * inData, /* in */ + UINT32 randomSize, /* in */ + BYTE * random, /* in */ + TPM_AUTH * parentAuth, /* in, out */ + UINT32 * outDataSize, /* out */ + BYTE ** outData) /* out */ +{ + UINT64 offset; + TSS_RESULT result; + UINT32 handlesLen, dataLen, decLen; + TCS_HANDLE *handles, handle; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + BYTE *data, *dec; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(parentHandle, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + handlesLen = 1; + handle = parentHandle; + handles = &handle; + + dataLen = (2 * sizeof(UINT32)) + randomSize + inDataSize; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, inDataSize, data); + Trspi_LoadBlob(&offset, inDataSize, data, inData); + Trspi_LoadBlob_UINT32(&offset, randomSize, data); + Trspi_LoadBlob(&offset, randomSize, data, random); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_ConvertMigrationBlob, + dataLen, data, &pubKeyHash, &handlesLen, + &handles, parentAuth, NULL, &decLen, &dec))) { + free(data); + return result; + } + free(data); + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, outDataSize, dec); + + if ((*outData = malloc(*outDataSize)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *outDataSize); + *outDataSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *outDataSize, dec, *outData); + free(dec); + + return result; +} + +TSS_RESULT +Transport_AuthorizeMigrationKey(TSS_HCONTEXT tspContext, /* in */ + TCPA_MIGRATE_SCHEME migrateScheme, /* in */ + UINT32 MigrationKeySize, /* in */ + BYTE * MigrationKey, /* in */ + TPM_AUTH * ownerAuth, /* in, out */ + UINT32 * MigrationKeyAuthSize, /* out */ + BYTE ** MigrationKeyAuth) /* out */ +{ + UINT64 offset; + UINT16 tpmMigrateScheme; + TSS_RESULT result; + UINT32 handlesLen = 0, dataLen, decLen; + BYTE *data, *dec; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + /* The TSS_MIGRATE_SCHEME must be changed to a TPM_MIGRATE_SCHEME here, since the TCS + * expects a TSS migrate scheme, but this could be wrapped by the TSP before it gets to the + * TCS. */ + switch (migrateScheme) { + case TSS_MS_MIGRATE: + tpmMigrateScheme = TCPA_MS_MIGRATE; + break; + case TSS_MS_REWRAP: + tpmMigrateScheme = TCPA_MS_REWRAP; + break; + case TSS_MS_MAINT: + tpmMigrateScheme = TCPA_MS_MAINT; + break; +#ifdef TSS_BUILD_CMK + case TSS_MS_RESTRICT_MIGRATE: + tpmMigrateScheme = TPM_MS_RESTRICT_MIGRATE; + break; + + case TSS_MS_RESTRICT_APPROVE_DOUBLE: + tpmMigrateScheme = TPM_MS_RESTRICT_APPROVE_DOUBLE; + break; +#endif + default: + return TSPERR(TSS_E_BAD_PARAMETER); + break; + } + + dataLen = sizeof(TCPA_MIGRATE_SCHEME) + MigrationKeySize; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob_UINT16(&offset, tpmMigrateScheme, data); + Trspi_LoadBlob(&offset, MigrationKeySize, data, MigrationKey); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_AuthorizeMigrationKey, + dataLen, data, NULL, &handlesLen, NULL, + ownerAuth, NULL, &decLen, &dec))) { + free(data); + return result; + } + free(data); + + *MigrationKeyAuthSize = decLen; + *MigrationKeyAuth = dec; + + return result; +} + +#endif + diff --git a/src/tspi/tsp_nv.c b/src/tspi/tsp_nv.c new file mode 100644 index 0000000..511a6c9 --- /dev/null +++ b/src/tspi/tsp_nv.c @@ -0,0 +1,245 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_NV_DefineOrReleaseSpace(TSS_HCONTEXT tspContext, /* in */ + UINT32 cPubInfoSize, /* in */ + BYTE* pPubInfo, /* in */ + TCPA_ENCAUTH encAuth, /* in */ + TPM_AUTH* pAuth) /* in, out */ +{ + TSS_RESULT result; + UINT32 dataLen; + UINT64 offset; + TCS_HANDLE handlesLen = 0; + BYTE *data; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + dataLen = sizeof(TCPA_ENCAUTH) + cPubInfoSize; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob(&offset, cPubInfoSize, data, pPubInfo); + Trspi_LoadBlob(&offset, TPM_SHA1_160_HASH_LEN, data, encAuth.authdata); + + result = obj_context_transport_execute(tspContext, TPM_ORD_NV_DefineSpace, dataLen, data, + NULL, &handlesLen, NULL, pAuth, NULL, NULL, NULL); + free(data); + + return result; +} + +TSS_RESULT +Transport_NV_WriteValue(TSS_HCONTEXT tspContext, /* in */ + TSS_NV_INDEX hNVStore, /* in */ + UINT32 offset, /* in */ + UINT32 ulDataLength, /* in */ + BYTE* rgbDataToWrite, /* in */ + TPM_AUTH* privAuth) /* in, out */ +{ + TSS_RESULT result; + UINT32 dataLen; + UINT64 offset64; + TCS_HANDLE handlesLen = 0; + BYTE *data; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + dataLen = sizeof(TSS_NV_INDEX) + (2 * sizeof(UINT32)) + ulDataLength; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset64 = 0; + Trspi_LoadBlob_UINT32(&offset64, hNVStore, data); + Trspi_LoadBlob_UINT32(&offset64, offset, data); + Trspi_LoadBlob_UINT32(&offset64, ulDataLength, data); + Trspi_LoadBlob(&offset64, ulDataLength, data, rgbDataToWrite); + + result = obj_context_transport_execute(tspContext, TPM_ORD_NV_WriteValue, dataLen, data, + NULL, &handlesLen, NULL, privAuth, NULL, NULL, NULL); + free(data); + + return result; +} + +TSS_RESULT +Transport_NV_WriteValueAuth(TSS_HCONTEXT tspContext, /* in */ + TSS_NV_INDEX hNVStore, /* in */ + UINT32 offset, /* in */ + UINT32 ulDataLength, /* in */ + BYTE* rgbDataToWrite, /* in */ + TPM_AUTH* NVAuth) /* in, out */ +{ + TSS_RESULT result; + UINT32 dataLen; + UINT64 offset64; + TCS_HANDLE handlesLen = 0; + BYTE *data; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + dataLen = sizeof(TSS_NV_INDEX) + (2 * sizeof(UINT32)) + ulDataLength; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset64 = 0; + Trspi_LoadBlob_UINT32(&offset64, hNVStore, data); + Trspi_LoadBlob_UINT32(&offset64, offset, data); + Trspi_LoadBlob_UINT32(&offset64, ulDataLength, data); + Trspi_LoadBlob(&offset64, ulDataLength, data, rgbDataToWrite); + + result = obj_context_transport_execute(tspContext, TPM_ORD_NV_WriteValueAuth, dataLen, data, + NULL, &handlesLen, NULL, NVAuth, NULL, NULL, NULL); + free(data); + + return result; +} + + +TSS_RESULT +Transport_NV_ReadValue(TSS_HCONTEXT tspContext, /* in */ + TSS_NV_INDEX hNVStore, /* in */ + UINT32 offset, /* in */ + UINT32* pulDataLength, /* in, out */ + TPM_AUTH* privAuth, /* in, out */ + BYTE** rgbDataRead) /* out */ +{ + TSS_RESULT result; + UINT32 dataLen, decLen; + UINT64 offset64; + TCS_HANDLE handlesLen = 0; + BYTE *data, *dec; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + dataLen = sizeof(TSS_NV_INDEX) + sizeof(UINT32) + *pulDataLength; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset64 = 0; + Trspi_LoadBlob_UINT32(&offset64, hNVStore, data); + Trspi_LoadBlob_UINT32(&offset64, offset, data); + Trspi_LoadBlob_UINT32(&offset64, *pulDataLength, data); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_NV_ReadValue, dataLen, data, + NULL, &handlesLen, NULL, privAuth, NULL, + &decLen, &dec))) { + free(data); + return result; + } + free(data); + + offset64 = 0; + Trspi_UnloadBlob_UINT32(&offset64, pulDataLength, dec); + + if ((*rgbDataRead = malloc(*pulDataLength)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *pulDataLength); + *pulDataLength = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset64, *pulDataLength, dec, *rgbDataRead); + free(dec); + + return result; +} + + +TSS_RESULT +Transport_NV_ReadValueAuth(TSS_HCONTEXT tspContext, /* in */ + TSS_NV_INDEX hNVStore, /* in */ + UINT32 offset, /* in */ + UINT32* pulDataLength, /* in, out */ + TPM_AUTH* NVAuth, /* in, out */ + BYTE** rgbDataRead) /* out */ +{ + TSS_RESULT result; + UINT32 dataLen, decLen; + UINT64 offset64; + TCS_HANDLE handlesLen = 0; + BYTE *data, *dec; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + dataLen = sizeof(TSS_NV_INDEX) + sizeof(UINT32) + *pulDataLength; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset64 = 0; + Trspi_LoadBlob_UINT32(&offset64, hNVStore, data); + Trspi_LoadBlob_UINT32(&offset64, offset, data); + Trspi_LoadBlob_UINT32(&offset64, *pulDataLength, data); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_NV_ReadValueAuth, dataLen, + data, NULL, &handlesLen, NULL, NVAuth, NULL, + &decLen, &dec))) { + free(data); + return result; + } + free(data); + + offset64 = 0; + Trspi_UnloadBlob_UINT32(&offset64, pulDataLength, dec); + + if ((*rgbDataRead = malloc(*pulDataLength)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *pulDataLength); + *pulDataLength = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset64, *pulDataLength, dec, *rgbDataRead); + free(dec); + + return result; +} + +#endif diff --git a/src/tspi/tsp_oper.c b/src/tspi/tsp_oper.c new file mode 100644 index 0000000..092b5ce --- /dev/null +++ b/src/tspi/tsp_oper.c @@ -0,0 +1,48 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <errno.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_SetOperatorAuth(TSS_HCONTEXT tspContext, /* in */ + TCPA_SECRET *operatorAuth) /* in */ +{ + TSS_RESULT result; + UINT64 offset; + TCS_HANDLE handlesLen = 0; + BYTE data[sizeof(TCPA_SECRET)]; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + offset = 0; + Trspi_LoadBlob(&offset, TPM_SHA1_160_HASH_LEN, data, operatorAuth->authdata); + + return obj_context_transport_execute(tspContext, TPM_ORD_SetOperatorAuth, sizeof(data), + data, NULL, &handlesLen, NULL, NULL, NULL, NULL, NULL); +} +#endif diff --git a/src/tspi/tsp_own.c b/src/tspi/tsp_own.c new file mode 100644 index 0000000..812277a --- /dev/null +++ b/src/tspi/tsp_own.c @@ -0,0 +1,193 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <errno.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +secret_TakeOwnership(TSS_HKEY hEndorsementPubKey, + TSS_HTPM hTPM, + TSS_HKEY hKeySRK, + TPM_AUTH * auth, + UINT32 * encOwnerAuthLength, + BYTE * encOwnerAuth, UINT32 * encSRKAuthLength, BYTE * encSRKAuth) +{ + TSS_RESULT result; + UINT32 endorsementKeySize; + BYTE *endorsementKey; + TSS_KEY dummyKey; + UINT64 offset; + TCPA_SECRET ownerSecret; + TCPA_SECRET srkSecret; + TCPA_DIGEST digest; + TSS_HPOLICY hSrkPolicy; + TSS_HPOLICY hOwnerPolicy; + UINT32 srkKeyBlobLength; + BYTE *srkKeyBlob; + TSS_HCONTEXT tspContext; + UINT32 ownerMode, srkMode; + Trspi_HashCtx hashCtx; + + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + /************************************************* + * First, get the policy objects and check them for how + * to handle the secrets. If they cannot be found + * or there is an error, then we must fail + **************************************************/ + + /* First get the Owner Policy */ + if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hOwnerPolicy))) + return result; + + /* Now get the SRK Policy */ + if ((result = obj_rsakey_get_policy(hKeySRK, TSS_POLICY_USAGE, &hSrkPolicy, NULL))) + return result; + + if ((result = obj_policy_get_mode(hOwnerPolicy, &ownerMode))) + return result; + + if ((result = obj_policy_get_mode(hSrkPolicy, &srkMode))) + return result; + + /* If the policy callback's aren't the same, that's an error if one is callback */ + if (srkMode == TSS_SECRET_MODE_CALLBACK || ownerMode == TSS_SECRET_MODE_CALLBACK) { + if (srkMode != TSS_SECRET_MODE_CALLBACK || ownerMode != TSS_SECRET_MODE_CALLBACK) { + LogError("Policy callback modes for SRK policy and Owner policy differ."); + return TSPERR(TSS_E_BAD_PARAMETER); + } + } + + if (ownerMode != TSS_SECRET_MODE_CALLBACK) { + /* First, get the Endorsement Public Key for Encrypting */ + if ((result = obj_rsakey_get_blob(hEndorsementPubKey, &endorsementKeySize, + &endorsementKey))) + return result; + + /* now stick it in a Key Structure */ + offset = 0; + if ((result = UnloadBlob_TSS_KEY(&offset, endorsementKey, &dummyKey))) { + free_tspi(tspContext, endorsementKey); + return result; + } + free_tspi(tspContext, endorsementKey); + + if ((result = obj_policy_get_secret(hOwnerPolicy, TR_SECRET_CTX_NEW, + &ownerSecret))) { + free(dummyKey.pubKey.key); + free(dummyKey.algorithmParms.parms); + return result; + } + + if ((result = obj_policy_get_secret(hSrkPolicy, TR_SECRET_CTX_NEW, &srkSecret))) { + free(dummyKey.pubKey.key); + free(dummyKey.algorithmParms.parms); + return result; + } + + /* Encrypt the Owner, SRK Authorizations */ + if ((result = Trspi_RSA_Encrypt(ownerSecret.authdata, 20, encOwnerAuth, + encOwnerAuthLength, dummyKey.pubKey.key, + dummyKey.pubKey.keyLength))) { + free(dummyKey.pubKey.key); + free(dummyKey.algorithmParms.parms); + return result; + } + + if ((result = Trspi_RSA_Encrypt(srkSecret.authdata, 20, encSRKAuth, + encSRKAuthLength, dummyKey.pubKey.key, + dummyKey.pubKey.keyLength))) { + free(dummyKey.pubKey.key); + free(dummyKey.algorithmParms.parms); + return result; + } + + free(dummyKey.pubKey.key); + free(dummyKey.algorithmParms.parms); + } else { + *encOwnerAuthLength = 256; + *encSRKAuthLength = 256; + if ((result = obj_policy_do_takeowner(hOwnerPolicy, hTPM, hEndorsementPubKey, + *encOwnerAuthLength, encOwnerAuth))) + return result; + } + + if ((result = obj_rsakey_get_blob(hKeySRK, &srkKeyBlobLength, &srkKeyBlob))) + return result; + + /* Authorizatin Digest Calculation */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_TakeOwnership); + result |= Trspi_Hash_UINT16(&hashCtx, TCPA_PID_OWNER); + result |= Trspi_Hash_UINT32(&hashCtx, *encOwnerAuthLength); + result |= Trspi_HashUpdate(&hashCtx, *encOwnerAuthLength, encOwnerAuth); + result |= Trspi_Hash_UINT32(&hashCtx, *encSRKAuthLength); + result |= Trspi_HashUpdate(&hashCtx, *encSRKAuthLength, encSRKAuth); + result |= Trspi_HashUpdate(&hashCtx, srkKeyBlobLength, srkKeyBlob); + free_tspi(tspContext, srkKeyBlob); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + /* HMAC for the final digest */ + if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_TakeOwnership, hOwnerPolicy, FALSE, + &digest, auth))) + return result; + + return TSS_SUCCESS; +} + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_OwnerClear(TSS_HCONTEXT tspContext, /* in */ + TPM_AUTH * ownerAuth) /* in, out */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + return obj_context_transport_execute(tspContext, TPM_ORD_OwnerClear, 0, NULL, NULL, + &handlesLen, NULL, ownerAuth, NULL, NULL, NULL); +} + +TSS_RESULT +Transport_ForceClear(TSS_HCONTEXT tspContext) /* in */ +{ + TSS_RESULT result; + UINT32 handlesLen = 0; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + return obj_context_transport_execute(tspContext, TPM_ORD_ForceClear, 0, NULL, NULL, + &handlesLen, NULL, NULL, NULL, NULL, NULL); +} +#endif + diff --git a/src/tspi/tsp_pcr.c b/src/tspi/tsp_pcr.c new file mode 100644 index 0000000..cc562d7 --- /dev/null +++ b/src/tspi/tsp_pcr.c @@ -0,0 +1,148 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <errno.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +UINT16 +get_num_pcrs(TSS_HCONTEXT tspContext) +{ + TSS_RESULT result; + static UINT16 ret = 0; + UINT32 subCap; + UINT32 respSize; + BYTE *resp; + + if (ret != 0) + return ret; + + subCap = endian32(TPM_CAP_PROP_PCR); + if ((result = TCS_API(tspContext)->GetTPMCapability(tspContext, TPM_CAP_PROPERTY, + sizeof(UINT32), (BYTE *)&subCap, + &respSize, &resp))) { + if ((resp = (BYTE *)getenv("TSS_DEFAULT_NUM_PCRS")) == NULL) + return TSS_DEFAULT_NUM_PCRS; + + /* don't set ret here, next time we may be connected */ + return atoi((char *)resp); + } + + ret = (UINT16)Decode_UINT32(resp); + free(resp); + + return ret; +} + +TSS_RESULT +pcrs_calc_composite(TPM_PCR_SELECTION *select, TPM_PCRVALUE *arrayOfPcrs, TPM_DIGEST *digestOut) +{ + UINT32 size, index; + BYTE mask; + BYTE hashBlob[1024]; + UINT32 numPCRs = 0; + UINT64 offset = 0; + UINT64 sizeOffset = 0; + + if (select->sizeOfSelect > 0) { + sizeOffset = 0; + Trspi_LoadBlob_PCR_SELECTION(&sizeOffset, hashBlob, select); + offset = sizeOffset + 4; + + for (size = 0; size < select->sizeOfSelect; size++) { + for (index = 0, mask = 1; index < 8; index++, mask = mask << 1) { + if (select->pcrSelect[size] & mask) { + memcpy(&hashBlob[(numPCRs * TPM_SHA1_160_HASH_LEN) + offset], + arrayOfPcrs[index + (size << 3)].digest, + TPM_SHA1_160_HASH_LEN); + numPCRs++; + } + } + } + + if (numPCRs > 0) { + offset += (numPCRs * TPM_SHA1_160_HASH_LEN); + UINT32ToArray(numPCRs * TPM_SHA1_160_HASH_LEN, &hashBlob[sizeOffset]); + + return Trspi_Hash(TSS_HASH_SHA1, offset, hashBlob, digestOut->digest); + } + } + + return TSPERR(TSS_E_INTERNAL_ERROR); +} + +TSS_RESULT +pcrs_sanity_check_selection(TSS_HCONTEXT tspContext, + struct tr_pcrs_obj *pcrs, + TPM_PCR_SELECTION *select) +{ + UINT16 num_pcrs, bytes_to_hold; + + if ((num_pcrs = get_num_pcrs(tspContext)) == 0) + return TSPERR(TSS_E_INTERNAL_ERROR); + + bytes_to_hold = num_pcrs / 8; + + /* Is the current select object going to be interpretable by the TPM? + * If the select object is of a size greater than the one the TPM + * wants, just calculate the composite hash and let the TPM return an + * error code to the user. If its less than the size of the one the + * TPM wants, add extra zero bytes until its the right size. */ + if (bytes_to_hold > select->sizeOfSelect) { + if ((select->pcrSelect = realloc(select->pcrSelect, bytes_to_hold)) == NULL) { + LogError("malloc of %hu bytes failed.", bytes_to_hold); + return TSPERR(TSS_E_OUTOFMEMORY); + } + /* set the newly allocated bytes to 0 */ + memset(&select->pcrSelect[select->sizeOfSelect], 0, + bytes_to_hold - select->sizeOfSelect); + select->sizeOfSelect = bytes_to_hold; + + /* realloc the pcr array as well */ + if ((pcrs->pcrs = realloc(pcrs->pcrs, + (bytes_to_hold * 8) * TPM_SHA1_160_HASH_LEN)) == NULL) { + LogError("malloc of %d bytes failed.", + (bytes_to_hold * 8) * TPM_SHA1_160_HASH_LEN); + return TSPERR(TSS_E_OUTOFMEMORY); + } + } + +#ifdef TSS_DEBUG + { + int i; + for (i = 0; i < select->sizeOfSelect * 8; i++) { + if (select->pcrSelect[i/8] & (1 << (i % 8))) { + LogDebug("PCR%d: Selected", i); + LogBlobData(APPID, TPM_SHA1_160_HASH_LEN, + (unsigned char *)&pcrs->pcrs[i]); + } else { + LogDebug("PCR%d: Not Selected", i); + } + } + } +#endif + + return TSS_SUCCESS; +} diff --git a/src/tspi/tsp_pcr_extend.c b/src/tspi/tsp_pcr_extend.c new file mode 100644 index 0000000..cd7ada1 --- /dev/null +++ b/src/tspi/tsp_pcr_extend.c @@ -0,0 +1,112 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <errno.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_Extend(TSS_HCONTEXT tspContext, /* in */ + TCPA_PCRINDEX pcrNum, /* in */ + TCPA_DIGEST inDigest, /* in */ + TCPA_PCRVALUE * outDigest) /* out */ +{ + TSS_RESULT result; + UINT64 offset; + TCS_HANDLE handlesLen = 0; + UINT32 decLen; + BYTE data[sizeof(TCPA_PCRINDEX) + sizeof(TCPA_DIGEST)], *dec; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, pcrNum, data); + Trspi_LoadBlob(&offset, TPM_SHA1_160_HASH_LEN, data, inDigest.digest); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Extend, sizeof(data), data, + NULL, &handlesLen, NULL, NULL, NULL, &decLen, + &dec))) + return result; + + offset = 0; + Trspi_UnloadBlob(&offset, decLen, dec, outDigest->digest); + + free(dec); + + return TSS_SUCCESS; +} + +TSS_RESULT +Transport_PcrRead(TSS_HCONTEXT tspContext, /* in */ + TCPA_PCRINDEX pcrNum, /* in */ + TCPA_PCRVALUE * outDigest) /* out */ +{ + TSS_RESULT result; + UINT64 offset; + TCS_HANDLE handlesLen = 0; + UINT32 decLen; + BYTE data[sizeof(TCPA_PCRINDEX)], *dec; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, pcrNum, data); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_PcrRead, sizeof(data), + data, NULL, &handlesLen, NULL, NULL, NULL, + &decLen, &dec))) + return result; + + offset = 0; + Trspi_UnloadBlob(&offset, decLen, dec, outDigest->digest); + + free(dec); + + return TSS_SUCCESS; +} + + +TSS_RESULT +Transport_PcrReset(TSS_HCONTEXT tspContext, /* in */ + UINT32 pcrDataSizeIn, /* in */ + BYTE * pcrDataIn) /* in */ +{ + TSS_RESULT result; + TCS_HANDLE handlesLen = 0; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + return obj_context_transport_execute(tspContext, TPM_ORD_PCR_Reset, pcrDataSizeIn, + pcrDataIn, NULL, &handlesLen, NULL, NULL, NULL, NULL, + NULL); +} +#endif diff --git a/src/tspi/tsp_policy.c b/src/tspi/tsp_policy.c new file mode 100644 index 0000000..9d5ec5d --- /dev/null +++ b/src/tspi/tsp_policy.c @@ -0,0 +1,123 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004, 2005 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/mman.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + +#define PGSIZE sysconf(_SC_PAGESIZE) +#define PGOFFSET (PGSIZE - 1) +#define PGMASK (~PGOFFSET) + +/* + * popup_GetSecret() + * + * newPIN - non-zero to popup the dialog to enter a new PIN, zero to popup a dialog + * to enter an existing PIN + * hash_mode - flag indicating whether to include null terminating data in the hash + * of the secret (1.2 backport only). + * popup_str - string to appear in the title bar of the popup dialog + * auth_hash - the 20+ byte buffer that receives the SHA1 hash of the auth data + * entered into the dialog box + * + */ +TSS_RESULT +popup_GetSecret(UINT32 new_pin, UINT32 hash_mode, BYTE *popup_str, void *auth_hash) +{ + BYTE secret[UI_MAX_SECRET_STRING_LENGTH] = { 0 }; + BYTE *dflt = (BYTE *)"TSS Authentication Dialog"; + UINT32 secret_len = 0; + TSS_RESULT result; + + if (popup_str == NULL) + popup_str = dflt; + + /* pin the area where the secret will be put in memory */ + if (pin_mem(&secret, UI_MAX_SECRET_STRING_LENGTH)) { + LogError("Failed to pin secret in memory."); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + if (new_pin) + DisplayNewPINWindow(secret, &secret_len, popup_str); + else + DisplayPINWindow(secret, &secret_len, popup_str); + + if (!secret_len) { + unpin_mem(&secret, UI_MAX_SECRET_STRING_LENGTH); + return TSPERR(TSS_E_POLICY_NO_SECRET); + } + + if (hash_mode == TSS_TSPATTRIB_HASH_MODE_NOT_NULL) + secret_len -= sizeof(TSS_UNICODE); // Take off the NULL terminator + + LogDebug("Hashing these %u bytes as the secret:", secret_len); + LogDebugData(secret_len, secret); + result = Trspi_Hash(TSS_HASH_SHA1, secret_len, secret, auth_hash); + + /* zero, then unpin the memory */ + memset(secret, 0, secret_len); + unpin_mem(&secret, UI_MAX_SECRET_STRING_LENGTH); + + return result; +} + +int +pin_mem(void *addr, size_t len) +{ + /* only root can lock pages into RAM */ + if (getuid() != (uid_t)0) { + LogWarn("Not pinning secrets in memory due to insufficient perms."); + return 0; + } + + len += (uintptr_t)addr & PGOFFSET; + addr = (void *)((uintptr_t)addr & PGMASK); + if (mlock(addr, len) == -1) { + LogError("mlock: %s", strerror(errno)); + return 1; + } + + return 0; +} + +int +unpin_mem(void *addr, size_t len) +{ + /* only root can lock pages into RAM */ + if (getuid() != (uid_t)0) { + return 0; + } + + len += (uintptr_t)addr & PGOFFSET; + addr = (void *)((uintptr_t)addr & PGMASK); + if (munlock(addr, len) == -1) { + LogError("mlock: %s", strerror(errno)); + return 1; + } + + return 0; +} + + diff --git a/src/tspi/tsp_ps.c b/src/tspi/tsp_ps.c new file mode 100644 index 0000000..96c267a --- /dev/null +++ b/src/tspi/tsp_ps.c @@ -0,0 +1,347 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <limits.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/file.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <limits.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "tcs_tsp.h" +#include "tspps.h" +#include "tsplog.h" +#include "obj.h" + +/* + * tsp_ps.c + * + * Functions used to query the user persistent storage file. + * + * Since other apps may be altering the file, all operations must be atomic WRT the file and no + * cache will be kept, since another app could delete keys from the file out from under us. + * + * Atomicity is guaranteed for operations inbetween calls to get_file() and put_file(). + * + * A PS file will have the lifetime of the TSP context. For instance, this code will store hKeyA + * and hKeyB in the file "a": + * + * setenv("TSS_USER_PS_FILE=a"); + * Tspi_Context_Create(&hContext); + * Tspi_Context_RegisterKey(hKeyA); + * setenv("TSS_USER_PS_FILE=b"); + * Tspi_Context_RegisterKey(hKeyB); + * + * but this code will store hKeyA in file "a" and hKeyB in file "b": + * + * setenv("TSS_USER_PS_FILE=a"); + * Tspi_Context_Create(&hContext); + * Tspi_Context_RegisterKey(hKeyA); + * Tspi_Context_Close(hContext); + * + * setenv("TSS_USER_PS_FILE=b"); + * Tspi_Context_Create(&hContext); + * Tspi_Context_RegisterKey(hKeyB); + * + */ + +TSS_RESULT +ps_get_registered_keys(TSS_UUID *uuid, TSS_UUID *tcs_uuid, UINT32 *size, TSS_KM_KEYINFO **keys) +{ + int fd; + UINT32 result; + + if ((result = get_file(&fd))) + return result; + + result = psfile_get_registered_keys(fd, uuid, tcs_uuid, size, keys); + + put_file(fd); + + return result; +} + +TSS_RESULT +ps_get_registered_keys2(TSS_UUID *uuid, TSS_UUID *tcs_uuid, UINT32 *size, TSS_KM_KEYINFO2 **keys) +{ + int fd; + UINT32 result; + + if ((result = get_file(&fd))) + return result; + + /* Sets the proper TSS_KM_KEYINFO2 fields according to the UUID type */ + result = psfile_get_registered_keys2(fd, uuid, tcs_uuid, size, keys); + + put_file(fd); + + return result; +} + +TSS_RESULT +ps_is_key_registered(TSS_UUID *uuid, TSS_BOOL *answer) +{ + int fd; + TSS_RESULT result; + + if ((result = get_file(&fd))) + return result; + + result = psfile_is_key_registered(fd, uuid, answer); + + put_file(fd); + + return result; +} + +TSS_RESULT +ps_write_key(TSS_UUID *uuid, TSS_UUID *parent_uuid, UINT32 parent_ps, UINT32 blob_size, BYTE *blob) +{ + int fd; + TSS_RESULT result; + UINT16 short_blob_size = (UINT16)blob_size; + + if (blob_size > USHRT_MAX) { + LogError("Blob data being written to disk is too large(%u bytes)!", blob_size); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + if ((result = get_file(&fd))) + return result; + + result = psfile_write_key(fd, uuid, parent_uuid, parent_ps, blob, short_blob_size); + + put_file(fd); + return result; +} + + +TSS_RESULT +ps_remove_key(TSS_UUID *uuid) +{ + int fd; + TSS_RESULT result; + + if ((result = get_file(&fd))) + return result; + + result = psfile_remove_key(fd, uuid); + + put_file(fd); + return result; +} + +TSS_RESULT +ps_get_key_by_pub(TSS_HCONTEXT tspContext, UINT32 pub_size, BYTE *pub, TSS_HKEY *hKey) +{ + int fd; + TSS_RESULT result = TSS_SUCCESS; + BYTE key[4096]; + TSS_UUID uuid; + + if ((result = get_file(&fd))) + return result; + + if ((result = psfile_get_key_by_pub(fd, &uuid, pub_size, pub, key))) { + put_file(fd); + return result; + } + + put_file(fd); + + result = obj_rsakey_add_by_key(tspContext, &uuid, key, TSS_OBJ_FLAG_USER_PS, hKey); + + return result; +} + +TSS_RESULT +ps_get_key_by_uuid(TSS_HCONTEXT tspContext, TSS_UUID *uuid, TSS_HKEY *hKey) +{ + int fd; + TSS_RESULT result = TSS_SUCCESS; + BYTE key[4096]; + + if ((result = get_file(&fd))) + return result; + + if ((result = psfile_get_key_by_uuid(fd, uuid, key))) { + put_file(fd); + return result; + } + + put_file(fd); + + result = obj_rsakey_add_by_key(tspContext, uuid, key, TSS_OBJ_FLAG_USER_PS, hKey); + + return result; +} + +TSS_RESULT +ps_get_parent_uuid_by_uuid(TSS_UUID *uuid, TSS_UUID *parent_uuid) +{ + int fd; + TSS_RESULT result; + + if ((result = get_file(&fd))) + return result; + + result = psfile_get_parent_uuid_by_uuid(fd, uuid, parent_uuid); + + put_file(fd); + return result; +} + +TSS_RESULT +ps_get_parent_ps_type_by_uuid(TSS_UUID *uuid, UINT32 *type) +{ + int fd; + TSS_RESULT result; + + if ((result = get_file(&fd))) + return result; + + result = psfile_get_parent_ps_type(fd, uuid, type); + + put_file(fd); + + return result; +} + +TSS_RESULT +ps_close() +{ + TSS_RESULT result; + int fd; + + if ((result = get_file(&fd))) + return result; + + psfile_close(fd); + + /* No need to call put_file() here, the file is closed */ + + return TSS_SUCCESS; +} + +TSS_RESULT +merge_key_hierarchies(TSS_HCONTEXT tspContext, UINT32 tsp_size, TSS_KM_KEYINFO *tsp_hier, + UINT32 tcs_size, TSS_KM_KEYINFO *tcs_hier, UINT32 *merged_size, + TSS_KM_KEYINFO **merged_hier) +{ + UINT32 i, j; + + *merged_hier = malloc((tsp_size + tcs_size) * sizeof(TSS_KM_KEYINFO)); + if (*merged_hier == NULL) { + LogError("malloc of %zu bytes failed.", (tsp_size + tcs_size) * + sizeof(TSS_KM_KEYINFO)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + for (i = 0; i < tsp_size; i++) + memcpy(&((*merged_hier)[i]), &tsp_hier[i], sizeof(TSS_KM_KEYINFO)); + + for (j = 0; j < tcs_size; j++) + memcpy(&((*merged_hier)[i + j]), &tcs_hier[j], sizeof(TSS_KM_KEYINFO)); + + *merged_size = i + j; + + return TSS_SUCCESS; +} + + +TSS_RESULT +merge_key_hierarchies2(TSS_HCONTEXT tspContext, UINT32 tsp_size, TSS_KM_KEYINFO2 *tsp_hier, + UINT32 tcs_size, TSS_KM_KEYINFO2 *tcs_hier, UINT32 *merged_size, + TSS_KM_KEYINFO2 **merged_hier) +{ + UINT32 i, j; + + *merged_hier = malloc((tsp_size + tcs_size) * sizeof(TSS_KM_KEYINFO2)); + if (*merged_hier == NULL) { + LogError("malloc of %zu bytes failed.", (tsp_size + tcs_size) * + sizeof(TSS_KM_KEYINFO2)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + for (i = 0; i < tsp_size; i++) + memcpy(&((*merged_hier)[i]), &tsp_hier[i], sizeof(TSS_KM_KEYINFO2)); + + for (j = 0; j < tcs_size; j++) + memcpy(&((*merged_hier)[i + j]), &tcs_hier[j], sizeof(TSS_KM_KEYINFO2)); + + *merged_size = i + j; + + return TSS_SUCCESS; +} + + +#if 0 +TSS_RESULT +load_from_system_ps(TSS_HCONTEXT tspContext, TSS_UUID *uuid, TSS_HKEY *phKey) +{ + TCS_KEY_HANDLE tcsKeyHandle; + TCS_LOADKEY_INFO info; + BYTE *keyBlob = NULL; + + memset(&info, 0, sizeof(TCS_LOADKEY_INFO)); + + result = TCSP_LoadKeyByUUID(tspContext, uuidData, &info, &tcsKeyHandle); + + if (TSS_ERROR_CODE(result) == TCS_E_KM_LOADFAILED) { + TSS_HKEY keyHandle; + TSS_HPOLICY hPolicy; + + /* load failed, due to some key in the chain needing auth + * which doesn't yet exist at the TCS level. However, the + * auth may already be set in policies at the TSP level. + * To find out, get the key handle of the key requiring + * auth. First, look at the list of keys in memory. */ + if ((obj_rsakey_get_by_uuid(&info.parentKeyUUID, &keyHandle))) { + /* If that failed, look on disk, in User PS. */ + if (ps_get_key_by_uuid(tspContext, &info.parentKeyUUID, &keyHandle)) + return result; + } + + if (obj_rsakey_get_policy(keyHandle, TSS_POLICY_USAGE, &hPolicy, NULL)) + return result; + + if (secret_PerformAuth_OIAP(keyHandle, TPM_ORD_LoadKey, hPolicy, &info.paramDigest, + &info.authData)) + return result; + + if ((result = TCSP_LoadKeyByUUID(tspContext, *uuid, &info, &tcsKeyHandle))) + return result; + } else if (result) + return result; + + if ((result = TCS_GetRegisteredKeyBlob(tspContext, *uuid, &keyBlobSize, &keyBlob))) + return result; + + if ((result = obj_rsakey_add_by_key(tspContext, uuid, keyBlob, TSS_OBJ_FLAG_SYSTEM_PS, + phKey))) { + free(keyBlob); + return result; + } + + result = obj_rsakey_set_tcs_handle(*phKey, tcsKeyHandle); + + free(keyBlob); + + return result; +} +#endif + diff --git a/src/tspi/tsp_quote.c b/src/tspi/tsp_quote.c new file mode 100644 index 0000000..24e026b --- /dev/null +++ b/src/tspi/tsp_quote.c @@ -0,0 +1,114 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_Quote(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + TCPA_NONCE *antiReplay, /* in */ + UINT32 pcrDataSizeIn, /* in */ + BYTE * pcrDataIn, /* in */ + TPM_AUTH * privAuth, /* in, out */ + UINT32 * pcrDataSizeOut, /* out */ + BYTE ** pcrDataOut, /* out */ + UINT32 * sigSize, /* out */ + BYTE ** sig) /* out */ +{ + TSS_RESULT result; + UINT32 handlesLen, dataLen, decLen; + TCS_HANDLE *handles, handle; + BYTE *dec = NULL; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + UINT64 offset; + BYTE *data; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + handlesLen = 1; + handle = keyHandle; + handles = &handle; + + dataLen = sizeof(TCPA_NONCE) + pcrDataSizeIn; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob_NONCE(&offset, data, antiReplay); + Trspi_LoadBlob(&offset, pcrDataSizeIn, data, pcrDataIn); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Quote, dataLen, data, + &pubKeyHash, &handlesLen, &handles, + privAuth, NULL, &decLen, &dec))) { + free(data); + return result; + } + free(data); + + offset = 0; + Trspi_UnloadBlob_PCR_COMPOSITE(&offset, dec, NULL); + *pcrDataSizeOut = offset; + + if ((*pcrDataOut = malloc(*pcrDataSizeOut)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *pcrDataSizeOut); + *pcrDataSizeOut = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_UnloadBlob(&offset, *pcrDataSizeOut, dec, *pcrDataOut); + Trspi_UnloadBlob_UINT32(&offset, sigSize, dec); + + if ((*sig = malloc(*sigSize)) == NULL) { + free(*pcrDataOut); + *pcrDataOut = NULL; + *pcrDataSizeOut = 0; + free(dec); + LogError("malloc of %u bytes failed", *sigSize); + *sigSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *sigSize, dec, *sig); + + free(dec); + + return result; +} +#endif + diff --git a/src/tspi/tsp_quote2.c b/src/tspi/tsp_quote2.c new file mode 100644 index 0000000..76ccc2e --- /dev/null +++ b/src/tspi/tsp_quote2.c @@ -0,0 +1,133 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_Quote2(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + TCPA_NONCE *antiReplay, /* in */ + UINT32 pcrDataSizeIn, /* in */ + BYTE * pcrDataIn, /* in */ + TSS_BOOL addVersion, /* in */ + TPM_AUTH * privAuth, /* in,out */ + UINT32 * pcrDataSizeOut, /* out */ + BYTE ** pcrDataOut, /* out */ + UINT32 * versionInfoSize, /* out */ + BYTE ** versionInfo, /* out */ + UINT32 * sigSize, /* out */ + BYTE ** sig) /* out */ +{ + TSS_RESULT result; + UINT32 handlesLen, dataLen, decLen; + TCS_HANDLE *handles, handle; + BYTE *dec = NULL; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + UINT64 offset; + BYTE *data; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + handlesLen = 1; + handle = keyHandle; + handles = &handle; + + dataLen = sizeof(TCPA_NONCE) + pcrDataSizeIn + sizeof(TSS_BOOL); + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob_NONCE(&offset, data, antiReplay); + Trspi_LoadBlob(&offset, pcrDataSizeIn, data, pcrDataIn); + Trspi_LoadBlob_BOOL(&offset, addVersion, data); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Quote2, dataLen, data, + &pubKeyHash, &handlesLen, &handles, + privAuth, NULL, &decLen, &dec))) { + free(data); + return result; + } + free(data); + + offset = 0; + Trspi_UnloadBlob_PCR_INFO_SHORT(&offset, dec, NULL); + *pcrDataSizeOut = offset; + + if ((*pcrDataOut = malloc(*pcrDataSizeOut)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *pcrDataSizeOut); + *pcrDataSizeOut = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_UnloadBlob(&offset, *pcrDataSizeOut, dec, *pcrDataOut); + Trspi_UnloadBlob_UINT32(&offset, versionInfoSize, dec); + + if ((*versionInfo = malloc(*versionInfoSize)) == NULL) { + free(*pcrDataOut); + *pcrDataOut = NULL; + *pcrDataSizeOut = 0; + free(dec); + LogError("malloc of %u bytes failed", *versionInfoSize); + *versionInfoSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *versionInfoSize, dec, *versionInfo); + + Trspi_UnloadBlob_UINT32(&offset, sigSize, dec); + + if ((*sig = malloc(*sigSize)) == NULL) { + free(*versionInfo); + *versionInfo = NULL; + *versionInfoSize = 0; + free(*pcrDataOut); + *pcrDataOut = NULL; + *pcrDataSizeOut = 0; + free(dec); + LogError("malloc of %u bytes failed", *sigSize); + *sigSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *sigSize, dec, *sig); + free(dec); + + return result; +} +#endif + diff --git a/src/tspi/tsp_random.c b/src/tspi/tsp_random.c new file mode 100644 index 0000000..80aff66 --- /dev/null +++ b/src/tspi/tsp_random.c @@ -0,0 +1,89 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004, 2007 + * + */ + + +#include <stdlib.h> +#include <syslog.h> +#include <unistd.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "tsplog.h" +#include "obj.h" + + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_GetRandom(TSS_HCONTEXT tspContext, /* in */ + UINT32 bytesRequested, /* in */ + BYTE ** randomBytes) /* out */ +{ + TSS_RESULT result; + UINT32 decLen = 0; + BYTE *dec = NULL; + UINT64 offset; + TCS_HANDLE handlesLen = 0; + BYTE data[sizeof(UINT32)]; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, bytesRequested, data); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetRandom, sizeof(data), + data, NULL, &handlesLen, NULL, NULL, NULL, + &decLen, &dec))) + return result; + + *randomBytes = dec; + + return result; + +} + +TSS_RESULT +Transport_StirRandom(TSS_HCONTEXT tspContext, /* in */ + UINT32 inDataSize, /* in */ + BYTE * inData) /* in */ +{ + TSS_RESULT result; + UINT64 offset; + UINT32 dataLen; + TCS_HANDLE handlesLen = 0; + BYTE *data; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + dataLen = sizeof(UINT32) + inDataSize; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, inDataSize, data); + Trspi_LoadBlob(&offset, inDataSize, data, inData); + + result = obj_context_transport_execute(tspContext, TPM_ORD_StirRandom, dataLen, data, NULL, + &handlesLen, NULL, NULL, NULL, NULL, NULL); + free(data); + + return result; +} +#endif + diff --git a/src/tspi/tsp_seal.c b/src/tspi/tsp_seal.c new file mode 100644 index 0000000..89c7ee0 --- /dev/null +++ b/src/tspi/tsp_seal.c @@ -0,0 +1,254 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "obj.h" +#include "tsplog.h" +#include "authsess.h" + + +#ifdef TSS_BUILD_SEALX +TSS_RESULT +sealx_mask_cb(PVOID lpAppData, + TSS_HKEY hEncKey, + TSS_HENCDATA hEncData, + TSS_ALGORITHM_ID algId, + UINT32 ulSizeNonces, + BYTE *rgbNonceEven, + BYTE *rgbNonceOdd, + BYTE *rgbNonceEvenOSAP, + BYTE *rgbNonceOddOSAP, + UINT32 ulDataLength, + BYTE *rgbDataToMask, + BYTE *rgbMaskedData) +{ + UINT32 mgf1SeedLen, sharedSecretLen = sizeof(TPM_DIGEST); + BYTE *mgf1Seed, *mgf1Buffer; + UINT32 i; + TSS_RESULT result; + struct authsess *sess = (struct authsess *)lpAppData; + + mgf1SeedLen = (ulSizeNonces * 2) + strlen("XOR") + sharedSecretLen; + if ((mgf1Seed = (BYTE *)calloc(1, mgf1SeedLen)) == NULL) { + LogError("malloc of %u bytes failed.", mgf1SeedLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + mgf1Buffer = mgf1Seed; + memcpy(mgf1Buffer, rgbNonceEven, ulSizeNonces); + mgf1Buffer += ulSizeNonces; + memcpy(mgf1Buffer, rgbNonceOdd, ulSizeNonces); + mgf1Buffer += ulSizeNonces; + memcpy(mgf1Buffer, "XOR", strlen("XOR")); + mgf1Buffer += strlen("XOR"); + memcpy(mgf1Buffer, sess->sharedSecret.digest, sharedSecretLen); + + if ((result = Trspi_MGF1(TSS_HASH_SHA1, mgf1SeedLen, mgf1Seed, ulDataLength, + rgbMaskedData))) + goto done; + + for (i = 0; i < ulDataLength; i++) + rgbMaskedData[i] ^= rgbDataToMask[i]; + +done: + free(mgf1Seed); + + return result; +} +#endif + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_Seal(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + TCPA_ENCAUTH *encAuth, /* in */ + UINT32 pcrInfoSize, /* in */ + BYTE * PcrInfo, /* in */ + UINT32 inDataSize, /* in */ + BYTE * inData, /* in */ + TPM_AUTH * pubAuth, /* in, out */ + UINT32 * SealedDataSize, /* out */ + BYTE ** SealedData) /* out */ +{ + TSS_RESULT result; + UINT32 handlesLen, decLen, dataLen; + TCS_HANDLE *handles, handle; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + UINT64 offset; + BYTE *data, *dec; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + handlesLen = 1; + handle = keyHandle; + handles = &handle; + + dataLen = (2 * sizeof(UINT32)) + sizeof(TPM_ENCAUTH) + pcrInfoSize + inDataSize; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob_DIGEST(&offset, data, (TPM_DIGEST *)encAuth); + Trspi_LoadBlob_UINT32(&offset, pcrInfoSize, data); + Trspi_LoadBlob(&offset, pcrInfoSize, data, PcrInfo); + Trspi_LoadBlob_UINT32(&offset, inDataSize, data); + Trspi_LoadBlob(&offset, inDataSize, data, inData); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Seal, dataLen, data, + &pubKeyHash, &handlesLen, &handles, pubAuth, + NULL, &decLen, &dec))) + return result; + + *SealedDataSize = decLen; + *SealedData = dec; + + return result; +} + +TSS_RESULT +Transport_Sealx(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + TCPA_ENCAUTH *encAuth, /* in */ + UINT32 pcrInfoSize, /* in */ + BYTE * PcrInfo, /* in */ + UINT32 inDataSize, /* in */ + BYTE * inData, /* in */ + TPM_AUTH * pubAuth, /* in, out */ + UINT32 * SealedDataSize, /* out */ + BYTE ** SealedData) /* out */ +{ + TSS_RESULT result; + UINT32 handlesLen, decLen, dataLen; + TCS_HANDLE *handles, handle; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + UINT64 offset; + BYTE *data, *dec; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + handlesLen = 1; + handle = keyHandle; + handles = &handle; + + dataLen = (2 * sizeof(UINT32)) + sizeof(TPM_ENCAUTH) + pcrInfoSize + inDataSize; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob(&offset, sizeof(TPM_ENCAUTH), data, encAuth->authdata); + Trspi_LoadBlob_UINT32(&offset, pcrInfoSize, data); + Trspi_LoadBlob(&offset, pcrInfoSize, data, PcrInfo); + Trspi_LoadBlob_UINT32(&offset, inDataSize, data); + Trspi_LoadBlob(&offset, inDataSize, data, inData); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Sealx, dataLen, data, + &pubKeyHash, &handlesLen, &handles, pubAuth, + NULL, &decLen, &dec))) + return result; + + *SealedDataSize = decLen; + *SealedData = dec; + + return result; +} + +TSS_RESULT +Transport_Unseal(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE parentHandle, /* in */ + UINT32 SealedDataSize, /* in */ + BYTE * SealedData, /* in */ + TPM_AUTH * parentAuth, /* in, out */ + TPM_AUTH * dataAuth, /* in, out */ + UINT32 * DataSize, /* out */ + BYTE ** Data) /* out */ +{ + UINT64 offset; + TSS_RESULT result; + UINT32 handlesLen, decLen; + TCS_HANDLE *handles, handle; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + BYTE *dec; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(parentHandle, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + handlesLen = 1; + handle = parentHandle; + handles = &handle; + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Unseal, SealedDataSize, + SealedData, &pubKeyHash, &handlesLen, &handles, + parentAuth, dataAuth, &decLen, &dec))) + return result; + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, DataSize, dec); + + if ((*Data = malloc(*DataSize)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *DataSize); + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *DataSize, dec, *Data); + + free(dec); + + return result; +} +#endif diff --git a/src/tspi/tsp_selftest.c b/src/tspi/tsp_selftest.c new file mode 100644 index 0000000..5a27110 --- /dev/null +++ b/src/tspi/tsp_selftest.c @@ -0,0 +1,132 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_SelfTestFull(TSS_HCONTEXT tspContext) +{ + TSS_RESULT result; + TCS_HANDLE handlesLen = 0; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + return obj_context_transport_execute(tspContext, TPM_ORD_SelfTestFull, 0, NULL, NULL, + &handlesLen, NULL, NULL, NULL, NULL, NULL); +} + +TSS_RESULT +Transport_CertifySelfTest(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + TCPA_NONCE antiReplay, /* in */ + TPM_AUTH * privAuth, /* in, out */ + UINT32 * sigSize, /* out */ + BYTE ** sig) /* out */ +{ + TSS_RESULT result; + UINT32 handlesLen, decLen = 0; + BYTE *dec = NULL; + UINT64 offset; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + TCS_HANDLE *handles, handle; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + handlesLen = 1; + handle = keyHandle; + handles = &handle; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_CertifySelfTest, + sizeof(TCPA_NONCE), antiReplay.nonce, + &pubKeyHash, &handlesLen, &handles, privAuth, + NULL, &decLen, &dec))) + return result; + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, sigSize, dec); + + if ((*sig = malloc(*sigSize)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *sigSize); + *sigSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *sigSize, dec, *sig); + + free(dec); + + return result; +} + +TSS_RESULT +Transport_GetTestResult(TSS_HCONTEXT tspContext, /* in */ + UINT32 * outDataSize, /* out */ + BYTE ** outData) /* out */ +{ + TSS_RESULT result; + UINT32 decLen = 0; + BYTE *dec = NULL; + UINT64 offset; + TCS_HANDLE handlesLen = 0; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetTestResult, 0, NULL, + NULL, &handlesLen, NULL, NULL, NULL, &decLen, + &dec))) + return result; + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, outDataSize, dec); + + if ((*outData = malloc(*outDataSize)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *outDataSize); + *outDataSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *outDataSize, dec, *outData); + + free(dec); + + return result; +} +#endif diff --git a/src/tspi/tsp_sign.c b/src/tspi/tsp_sign.c new file mode 100644 index 0000000..3a33cb6 --- /dev/null +++ b/src/tspi/tsp_sign.c @@ -0,0 +1,92 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + + +#include <stdlib.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_Sign(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE keyHandle, /* in */ + UINT32 areaToSignSize, /* in */ + BYTE * areaToSign, /* in */ + TPM_AUTH * privAuth, /* in, out */ + UINT32 * sigSize, /* out */ + BYTE ** sig) /* out */ +{ + UINT64 offset; + TSS_RESULT result; + UINT32 handlesLen, decLen, dataLen; + TCS_HANDLE *handles, handle; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + BYTE *dec, *data; + + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(keyHandle, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + handlesLen = 1; + handle = keyHandle; + handles = &handle; + + dataLen = sizeof(UINT32) + areaToSignSize; + if ((data = malloc(dataLen)) == NULL) { + LogError("malloc of %u bytes failed", dataLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, areaToSignSize, data); + Trspi_LoadBlob(&offset, areaToSignSize, data, areaToSign); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_Sign, dataLen, data, + &pubKeyHash, &handlesLen, &handles, + privAuth, NULL, &decLen, &dec))) { + free(data); + return result; + } + free(data); + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, sigSize, dec); + + if ((*sig = malloc(*sigSize)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *sigSize); + *sigSize = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *sigSize, dec, *sig); + + return result; +} +#endif + diff --git a/src/tspi/tsp_tick.c b/src/tspi/tsp_tick.c new file mode 100644 index 0000000..dd20bec --- /dev/null +++ b/src/tspi/tsp_tick.c @@ -0,0 +1,124 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +#ifdef TSS_BUILD_TRANSPORT +TSS_RESULT +Transport_ReadCurrentTicks(TSS_HCONTEXT tspContext, /* in */ + UINT32* pulCurrentTime, /* out */ + BYTE** prgbCurrentTime) /* out */ +{ + TSS_RESULT result; + UINT32 decLen = 0; + BYTE *dec = NULL; + TCS_HANDLE handlesLen = 0; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_GetTicks, 0, NULL, + NULL, &handlesLen, NULL, NULL, NULL, &decLen, + &dec))) + return result; + + *pulCurrentTime = decLen; + *prgbCurrentTime = dec; + + return TSS_SUCCESS; +} + +TSS_RESULT +Transport_TickStampBlob(TSS_HCONTEXT tspContext, /* in */ + TCS_KEY_HANDLE hKey, /* in */ + TPM_NONCE* antiReplay, /* in */ + TPM_DIGEST* digestToStamp, /* in */ + TPM_AUTH* privAuth, /* in, out */ + UINT32* pulSignatureLength, /* out */ + BYTE** prgbSignature, /* out */ + UINT32* pulTickCountLength, /* out */ + BYTE** prgbTickCount) /* out */ +{ + TSS_RESULT result; + UINT32 handlesLen, decLen = 0; + TCS_HANDLE *handles, handle; + BYTE *dec = NULL; + UINT64 offset; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + BYTE data[sizeof(TPM_NONCE) + sizeof(TPM_DIGEST)]; + + if ((result = obj_context_transport_init(tspContext))) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_tcskey_get_pubkeyhash(hKey, pubKeyHash.digest))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + handlesLen = 1; + handle = hKey; + handles = &handle; + + offset = 0; + Trspi_LoadBlob_NONCE(&offset, data, antiReplay); + Trspi_LoadBlob_DIGEST(&offset, data, digestToStamp); + + if ((result = obj_context_transport_execute(tspContext, TPM_ORD_TickStampBlob, sizeof(data), + data, &pubKeyHash, &handlesLen, &handles, + privAuth, NULL, &decLen, &dec))) + return result; + + offset = 0; + Trspi_UnloadBlob_CURRENT_TICKS(&offset, dec, NULL); + *pulTickCountLength = (UINT32)offset; + if ((*prgbTickCount = malloc(*pulTickCountLength)) == NULL) { + free(dec); + LogError("malloc of %u bytes failed", *pulTickCountLength); + return TSPERR(TSS_E_OUTOFMEMORY); + } + offset = 0; + Trspi_UnloadBlob(&offset, *pulTickCountLength, dec, *prgbTickCount); + + Trspi_UnloadBlob_UINT32(&offset, pulSignatureLength, dec); + if ((*prgbSignature = malloc(*pulSignatureLength)) == NULL) { + free(dec); + free(*prgbTickCount); + *pulTickCountLength = 0; + LogError("malloc of %u bytes failed", *pulSignatureLength); + *pulSignatureLength = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + Trspi_UnloadBlob(&offset, *pulSignatureLength, dec, *prgbSignature); + + free(dec); + + return result; +} +#endif diff --git a/src/tspi/tsp_transport.c b/src/tspi/tsp_transport.c new file mode 100644 index 0000000..1fa6611 --- /dev/null +++ b/src/tspi/tsp_transport.c @@ -0,0 +1,88 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Transport_LoadKeyByBlob(TSS_HCONTEXT hContext, + TPM_COMMAND_CODE ordinal, + TSS_HKEY hParentKey, + UINT32 ulBlobLength, + BYTE* rgbBlobData, + TPM_AUTH* pAuth, + TCS_KEY_HANDLE* phKey, + TPM_KEY_HANDLE* phSlot) +{ + TSS_RESULT result; + UINT32 handleListSize, decLen; + TCS_KEY_HANDLE hTCSParentKey; + TCS_HANDLE *handleList; + BYTE *dec = NULL; + TPM_DIGEST pubKeyHash; + Trspi_HashCtx hashCtx; + + + if ((result = obj_context_transport_init(hContext)) == TSS_TSPATTRIB_DISABLE_TRANSPORT) { + if ((result = obj_rsakey_get_tcs_handle(hParentKey, &hTCSParentKey))) + return result; + + return TCSP_LoadKeyByBlob(hContext, hTCSParentKey, ulBlobLength, rgbBlobData, pAuth, + phKey, phSlot); + } else if (result != TSS_TSPATTRIB_ENABLE_TRANSPORT) + return result; + + LogDebugFn("Executing in a transport session"); + + if ((result = obj_rsakey_get_transport_attribs(hParentKey, &hTCSParentKey, &pubKeyHash))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_DIGEST(&hashCtx, pubKeyHash.digest); + if ((result |= Trspi_HashFinal(&hashCtx, pubKeyHash.digest))) + return result; + + /* Call ExecuteTransport */ + handleListSize = 1; + if ((handleList = malloc(sizeof(TCS_HANDLE))) == NULL) { + LogError("malloc of %zd bytes failed", sizeof(TCS_HANDLE)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + *handleList = hTCSParentKey; + + if ((result = obj_context_transport_execute(hContext, ordinal, ulBlobLength, + rgbBlobData, &pubKeyHash, &handleListSize, + &handleList, pAuth, NULL, &decLen, &dec))) { + free(handleList); + return result; + } + + if (handleListSize == 1) + *phKey = *(TCS_KEY_HANDLE *)handleList; + else + result = TSPERR(TSS_E_INTERNAL_ERROR); + + free(handleList); + free(dec); + + return result; +} diff --git a/src/tspi/tspi_admin.c b/src/tspi/tspi_admin.c new file mode 100644 index 0000000..a20ab45 --- /dev/null +++ b/src/tspi/tspi_admin.c @@ -0,0 +1,362 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_TPM_SetStatus(TSS_HTPM hTPM, /* in */ + TSS_FLAG statusFlag, /* in */ + TSS_BOOL fTpmState) /* in */ +{ + TPM_AUTH auth, *pAuth; + TSS_RESULT result; + TCPA_DIGEST hashDigest; + TSS_HCONTEXT tspContext; + TSS_HPOLICY hPolicy; + TSS_HPOLICY hOperatorPolicy; + Trspi_HashCtx hashCtx; + UINT32 tpmVersion; + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy))) + return result; + + switch (statusFlag) { + case TSS_TPMSTATUS_DISABLEOWNERCLEAR: + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_DisableOwnerClear); + if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_DisableOwnerClear, hPolicy, + FALSE, &hashDigest, &auth))) + return result; + + if ((result = TCS_API(tspContext)->DisableOwnerClear(tspContext, &auth))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_DisableOwnerClear); + if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) + return result; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &hashDigest, &auth))) + return result; + break; + case TSS_TPMSTATUS_DISABLEFORCECLEAR: + result = TCS_API(tspContext)->DisableForceClear(tspContext); + break; + case TSS_TPMSTATUS_DISABLED: + case TSS_TPMSTATUS_OWNERSETDISABLE: + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerSetDisable); + result |= Trspi_Hash_BOOL(&hashCtx, fTpmState); + if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_OwnerSetDisable, hPolicy, + FALSE, &hashDigest, &auth))) + return result; + + if ((result = TCS_API(tspContext)->OwnerSetDisable(tspContext, fTpmState, &auth))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerSetDisable); + if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) + return result; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &hashDigest, &auth))) + return result; + break; + case TSS_TPMSTATUS_PHYSICALDISABLE: + if (fTpmState) + result = TCS_API(tspContext)->PhysicalDisable(tspContext); + else + result = TCS_API(tspContext)->PhysicalEnable(tspContext); + break; + case TSS_TPMSTATUS_DEACTIVATED: + case TSS_TPMSTATUS_PHYSICALSETDEACTIVATED: + result = TCS_API(tspContext)->PhysicalSetDeactivated(tspContext, fTpmState); + break; + case TSS_TPMSTATUS_SETTEMPDEACTIVATED: + if ((result = obj_context_get_tpm_version(tspContext, &tpmVersion))) + return result; + + /* XXX Change 0,1,2 to #defines */ + switch (tpmVersion) { + case 0: + case 1: + result = TCS_API(tspContext)->SetTempDeactivated(tspContext); + break; + case 2: + if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_OPERATOR, &hOperatorPolicy))) + return result; + + if (hOperatorPolicy != NULL_HPOLICY) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_SetTempDeactivated); + if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) + return result; + + pAuth = &auth; + if ((result = secret_PerformAuth_OIAP(hTPM, + TPM_ORD_SetTempDeactivated, + hOperatorPolicy, FALSE, + &hashDigest, pAuth))) + return result; + } + else + pAuth = NULL; + + if ((result = TCS_API(tspContext)->SetTempDeactivated2(tspContext, pAuth))) + return result; + + if (pAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_SetTempDeactivated); + if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) + return result; + + if ((result = obj_policy_validate_auth_oiap(hOperatorPolicy, + &hashDigest, + pAuth))) + return result; + } + break; + default: + return TSPERR(TSS_E_INTERNAL_ERROR); + } + break; + case TSS_TPMSTATUS_SETOWNERINSTALL: + result = TCS_API(tspContext)->SetOwnerInstall(tspContext, fTpmState); + break; + case TSS_TPMSTATUS_DISABLEPUBEKREAD: + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_DisablePubekRead); + if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_DisablePubekRead, hPolicy, + FALSE, &hashDigest, &auth))) + return result; + + if ((result = TCS_API(tspContext)->DisablePubekRead(tspContext, &auth))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_DisablePubekRead); + if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) + return result; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &hashDigest, &auth))) + return result; + break; + case TSS_TPMSTATUS_ALLOWMAINTENANCE: + /* Allow maintenance cannot be set to TRUE in the TPM */ + if (fTpmState) + return TSPERR(TSS_E_BAD_PARAMETER); + + /* The path to setting allow maintenance to FALSE is through + * KillMaintenanceFeature */ + return Tspi_TPM_KillMaintenanceFeature(hTPM); + break; +#ifdef TSS_BUILD_TSS12 + case TSS_TPMSTATUS_DISABLEPUBSRKREAD: + /* The logic of setting a 'disable' flag is reversed in the TPM, where setting this + * flag to TRUE will enable the SRK read, while FALSE disables it. So we need to + * flip the bool here. Sigh... */ + fTpmState = fTpmState ? FALSE : TRUE; + + result = TSP_SetCapability(tspContext, hTPM, hPolicy, TPM_SET_PERM_FLAGS, + TPM_PF_READSRKPUB, fTpmState); + break; + case TSS_TPMSTATUS_RESETLOCK: + /* ignoring the bool here */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ResetLockValue); + if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_ResetLockValue, hPolicy, + FALSE, &hashDigest, &auth))) + return result; + + if ((result = TCS_API(tspContext)->ResetLockValue(tspContext, &auth))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ResetLockValue); + if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) + return result; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &hashDigest, &auth))) + return result; + break; +#endif +#ifndef TSS_SPEC_COMPLIANCE + case TSS_TPMSTATUS_PHYSPRES_LIFETIMELOCK: + /* set the lifetime lock bit */ + result = TCS_API(tspContext)->PhysicalPresence(tspContext, + TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK); + break; + case TSS_TPMSTATUS_PHYSPRES_HWENABLE: + /* set the HW enable bit */ + result = TCS_API(tspContext)->PhysicalPresence(tspContext, + TPM_PHYSICAL_PRESENCE_HW_ENABLE); + break; + case TSS_TPMSTATUS_PHYSPRES_CMDENABLE: + /* set the command enable bit */ + result = TCS_API(tspContext)->PhysicalPresence(tspContext, + TPM_PHYSICAL_PRESENCE_CMD_ENABLE); + break; + case TSS_TPMSTATUS_PHYSPRES_LOCK: + /* set the physical presence lock bit */ + result = TCS_API(tspContext)->PhysicalPresence(tspContext, + TPM_PHYSICAL_PRESENCE_LOCK); + break; + case TSS_TPMSTATUS_PHYSPRESENCE: + /* set the physical presence state */ + result = TCS_API(tspContext)->PhysicalPresence(tspContext, (fTpmState ? + TPM_PHYSICAL_PRESENCE_PRESENT : + TPM_PHYSICAL_PRESENCE_NOTPRESENT)); + break; +#endif + default: + return TSPERR(TSS_E_BAD_PARAMETER); + break; + } + + return result; +} + +TSS_RESULT +Tspi_TPM_GetStatus(TSS_HTPM hTPM, /* in */ + TSS_FLAG statusFlag, /* in */ + TSS_BOOL * pfTpmState) /* out */ +{ + TSS_HCONTEXT tspContext; + TSS_RESULT result; + UINT32 nonVolFlags; + UINT32 volFlags; + + if (pfTpmState == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if ((result = get_tpm_flags(tspContext, hTPM, &volFlags, &nonVolFlags))) + return result; + + switch (statusFlag) { + case TSS_TPMSTATUS_DISABLEOWNERCLEAR: + *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_DISABLEOWNERCLEAR_BIT); + break; + case TSS_TPMSTATUS_DISABLEFORCECLEAR: + *pfTpmState = BOOL(volFlags & TSS_TPM_SF_DISABLEFORCECLEAR_BIT); + break; + case TSS_TPMSTATUS_DISABLED: + case TSS_TPMSTATUS_OWNERSETDISABLE: + *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_DISABLE_BIT); + break; + case TSS_TPMSTATUS_DEACTIVATED: + case TSS_TPMSTATUS_PHYSICALSETDEACTIVATED: + *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_DEACTIVATED_BIT); + break; + case TSS_TPMSTATUS_SETTEMPDEACTIVATED: + *pfTpmState = BOOL(volFlags & TSS_TPM_SF_DEACTIVATED_BIT); + break; + case TSS_TPMSTATUS_SETOWNERINSTALL: + *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_OWNERSHIP_BIT); + break; + case TSS_TPMSTATUS_DISABLEPUBEKREAD: + *pfTpmState = INVBOOL(nonVolFlags & TSS_TPM_PF_READPUBEK_BIT); + break; + case TSS_TPMSTATUS_ALLOWMAINTENANCE: + *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_ALLOWMAINTENANCE_BIT); + break; + case TSS_TPMSTATUS_MAINTENANCEUSED: + *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_MAINTENANCEDONE_BIT); + break; + case TSS_TPMSTATUS_PHYSPRES_LIFETIMELOCK: + *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_PHYSICALPRESENCELIFETIMELOCK_BIT); + break; + case TSS_TPMSTATUS_PHYSPRES_HWENABLE: + *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_PHYSICALPRESENCEHWENABLE_BIT); + break; + case TSS_TPMSTATUS_PHYSPRES_CMDENABLE: + *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_PHYSICALPRESENCECMDENABLE_BIT); + break; + case TSS_TPMSTATUS_CEKP_USED: + *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_CEKPUSED_BIT); + break; + case TSS_TPMSTATUS_PHYSPRESENCE: + *pfTpmState = BOOL(volFlags & TSS_TPM_SF_PHYSICALPRESENCE_BIT); + break; + case TSS_TPMSTATUS_PHYSPRES_LOCK: + *pfTpmState = BOOL(volFlags & TSS_TPM_SF_PHYSICALPRESENCELOCK_BIT); + break; + case TSS_TPMSTATUS_TPMPOST: + *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_TPMPOST_BIT); + break; + case TSS_TPMSTATUS_TPMPOSTLOCK: + *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_TPMPOSTLOCK_BIT); + break; + case TSS_TPMSTATUS_FIPS: + *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_FIPS_BIT); + break; + case TSS_TPMSTATUS_ENABLE_REVOKEEK: + *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_ENABLEREVOKEEK_BIT); + break; + case TSS_TPMSTATUS_TPM_ESTABLISHED: + *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_RESETESTABLISHMENTBIT_BIT); + break; + case TSS_TPMSTATUS_NV_LOCK: + *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_NV_LOCKED_BIT); + break; + case TSS_TPMSTATUS_POSTINITIALISE: + /* There is no way to query the TPM for this flag. */ + result = TSPERR(TSS_E_NOTIMPL); + break; +#ifdef TSS_BUILD_TSS12 + case TSS_TPMSTATUS_DISABLEPUBSRKREAD: + *pfTpmState = INVBOOL(nonVolFlags & TSS_TPM_PF_READSRKPUB_BIT); + break; + case TSS_TPMSTATUS_OPERATORINSTALLED: + *pfTpmState = BOOL(nonVolFlags & TSS_TPM_PF_OPERATOR_BIT); + break; +#endif + default: + return TSPERR(TSS_E_BAD_PARAMETER); + break; + } + + return TSS_SUCCESS; +} diff --git a/src/tspi/tspi_aik.c b/src/tspi/tspi_aik.c new file mode 100644 index 0000000..9476341 --- /dev/null +++ b/src/tspi/tspi_aik.c @@ -0,0 +1,579 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <limits.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> +#include <limits.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" +#include "authsess.h" + + +TSS_RESULT +Tspi_TPM_CollateIdentityRequest(TSS_HTPM hTPM, /* in */ + TSS_HKEY hKeySRK, /* in */ + TSS_HKEY hCAPubKey, /* in */ + UINT32 ulIdentityLabelLength, /* in */ + BYTE * rgbIdentityLabelData, /* in */ + TSS_HKEY hIdentityKey, /* in */ + TSS_ALGORITHM_ID algID, /* in */ + UINT32 * pulTcpaIdentityReqLength, /* out */ + BYTE ** prgbTcpaIdentityReq) /* out */ +{ +#ifdef TSS_BUILD_TRANSPORT + UINT32 transport; +#endif + TPM_AUTH srkAuth; + TCPA_RESULT result; + UINT64 offset; + BYTE hashblob[USHRT_MAX], idReqBlob[USHRT_MAX], testblob[USHRT_MAX]; + TCPA_DIGEST digest; + TSS_HPOLICY hSRKPolicy, hIDPolicy, hCAPolicy; + UINT32 caKeyBlobSize, idKeySize, idPubSize; + BYTE *caKeyBlob, *idKey, *newIdKey, *idPub; + TSS_KEY caKey; + TCPA_CHOSENID_HASH chosenIDHash = { { 0, } }; + UINT32 pcIdentityBindingSize; + BYTE *prgbIdentityBinding = NULL; + UINT32 pcEndorsementCredentialSize; + BYTE *prgbEndorsementCredential = NULL; + UINT32 pcPlatformCredentialSize; + BYTE *prgbPlatformCredential = NULL; + UINT32 pcConformanceCredentialSize; + BYTE *prgbConformanceCredential = NULL; +#define CHOSENID_BLOB_SIZE 2048 + BYTE chosenIDBlob[CHOSENID_BLOB_SIZE]; + TSS_HCONTEXT tspContext; + UINT32 encSymKeySize = 256, tmp; + BYTE encSymKey[256], *cb_var; + TSS_BOOL usesAuth; + TPM_AUTH *pSrkAuth = &srkAuth; + TCPA_IDENTITY_REQ rgbTcpaIdentityReq; + TCPA_KEY_PARMS symParms, asymParms; + TCPA_SYMMETRIC_KEY symKey; + int padding; + TSS_CALLBACK *cb; + Trspi_HashCtx hashCtx; + UINT32 tempCredSize; + BYTE *tempCred = NULL; + struct authsess *xsap = NULL; + + if (pulTcpaIdentityReqLength == NULL || prgbTcpaIdentityReq == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if ((result = obj_tpm_get_cb12(hTPM, TSS_TSPATTRIB_TPM_CALLBACK_COLLATEIDENTITY, &tmp, + &cb_var))) + return result; + + cb = (TSS_CALLBACK *)cb_var; + if (cb->callback == NULL) { + free_tspi(tspContext, cb); + cb = NULL; + } + + /* Get Policies */ + if ((result = obj_rsakey_get_policy(hKeySRK, TSS_POLICY_USAGE, &hSRKPolicy, &usesAuth))) + return result; + + if ((result = obj_rsakey_get_policy(hCAPubKey, TSS_POLICY_USAGE, + &hCAPolicy, NULL))) + return result; + + if ((result = obj_rsakey_get_policy(hIdentityKey, TSS_POLICY_USAGE, + &hIDPolicy, NULL))) + return result; + + /* setup the symmetric key's parms. */ + memset(&symParms, 0, sizeof(TCPA_KEY_PARMS)); + switch (algID) { + case TSS_ALG_AES: + symParms.algorithmID = TCPA_ALG_AES; + symKey.algId = TCPA_ALG_AES; + symKey.size = 128/8; + break; + case TSS_ALG_DES: + symParms.algorithmID = TCPA_ALG_DES; + symKey.algId = TCPA_ALG_DES; + symKey.size = 64/8; + break; + case TSS_ALG_3DES: + symParms.algorithmID = TCPA_ALG_3DES; + symKey.algId = TCPA_ALG_3DES; + symKey.size = 192/8; + break; + default: + result = TSPERR(TSS_E_BAD_PARAMETER); + goto error; + break; + } + + /* No symmetric key encryption schemes existed in the 1.1 time frame */ + symParms.encScheme = TCPA_ES_NONE; + + /* get the CA Pubkey's encryption scheme */ + if ((result = obj_rsakey_get_es(hCAPubKey, &tmp))) + return TSPERR(TSS_E_BAD_PARAMETER); + + switch (tmp) { + case TSS_ES_RSAESPKCSV15: + padding = TR_RSA_PKCS1_PADDING; + break; + case TSS_ES_RSAESOAEP_SHA1_MGF1: + padding = TR_RSA_PKCS1_OAEP_PADDING; + break; + case TSS_ES_NONE: + /* fall through */ + default: + padding = TR_RSA_NO_PADDING; + break; + } + + /* Get Key blobs */ + if ((result = obj_rsakey_get_blob(hIdentityKey, &idKeySize, &idKey))) + return result; + + if ((result = obj_rsakey_get_blob(hCAPubKey, &caKeyBlobSize, &caKeyBlob))) + return result; + + offset = 0; + memset(&caKey, 0, sizeof(TSS_KEY)); + if ((result = UnloadBlob_TSS_KEY(&offset, caKeyBlob, &caKey))) + return result; + + /* ChosenID hash = SHA1(label || TCPA_PUBKEY(CApub)) */ + offset = 0; + Trspi_LoadBlob(&offset, ulIdentityLabelLength, chosenIDBlob, rgbIdentityLabelData); + Trspi_LoadBlob_KEY_PARMS(&offset, chosenIDBlob, &caKey.algorithmParms); + Trspi_LoadBlob_STORE_PUBKEY(&offset, chosenIDBlob, &caKey.pubKey); + + if (offset > CHOSENID_BLOB_SIZE) + return TSPERR(TSS_E_INTERNAL_ERROR); + + if ((result = Trspi_Hash(TSS_HASH_SHA1, offset, chosenIDBlob, chosenIDHash.digest))) { + free_key_refs(&caKey); + return result; + } + + /* use chosenIDBlob temporarily */ + offset = 0; + Trspi_LoadBlob_KEY_PARMS(&offset, chosenIDBlob, &caKey.algorithmParms); + + offset = 0; + if ((result = Trspi_UnloadBlob_KEY_PARMS(&offset, chosenIDBlob, &asymParms))) + return result; + + if ((result = authsess_xsap_init(tspContext, hTPM, hIdentityKey, TSS_AUTH_POLICY_REQUIRED, + TPM_ORD_MakeIdentity, TPM_ET_OWNER, &xsap))) + return result; + + /* Hash the Auth data */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_MakeIdentity); + result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata); + result |= Trspi_HashUpdate(&hashCtx, TCPA_SHA1_160_HASH_LEN, chosenIDHash.digest); + result |= Trspi_HashUpdate(&hashCtx, idKeySize, idKey); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + /* Do the Auth's */ + if (usesAuth) { + if ((result = secret_PerformAuth_OIAP(hKeySRK, TPM_ORD_MakeIdentity, hSRKPolicy, + FALSE, &digest, &srkAuth))) + goto error; + pSrkAuth = &srkAuth; + } else { + pSrkAuth = NULL; + } + + if ((result = authsess_xsap_hmac(xsap, &digest))) + goto error; + +#ifdef TSS_BUILD_TRANSPORT + if ((result = obj_context_transport_get_control(tspContext, TSS_TSPATTRIB_ENABLE_TRANSPORT, + &transport))) + goto error; + + if (transport) { + if ((result = Transport_MakeIdentity2(tspContext, xsap->encAuthUse, chosenIDHash, + idKeySize, idKey, pSrkAuth, xsap->pAuth, + &idKeySize, &newIdKey, &pcIdentityBindingSize, + &prgbIdentityBinding))) + goto error; + } else { +#endif + if ((result = RPC_MakeIdentity(tspContext, xsap->encAuthUse, chosenIDHash, + idKeySize, idKey, pSrkAuth, xsap->pAuth, &idKeySize, + &newIdKey, &pcIdentityBindingSize, + &prgbIdentityBinding, &pcEndorsementCredentialSize, + &prgbEndorsementCredential, + &pcPlatformCredentialSize, &prgbPlatformCredential, + &pcConformanceCredentialSize, + &prgbConformanceCredential))) + goto error; +#ifdef TSS_BUILD_TRANSPORT + } +#endif + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_MakeIdentity); + result |= Trspi_HashUpdate(&hashCtx, idKeySize, newIdKey); + result |= Trspi_Hash_UINT32(&hashCtx, pcIdentityBindingSize); + result |= Trspi_HashUpdate(&hashCtx, pcIdentityBindingSize, prgbIdentityBinding); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) { + free(newIdKey); + goto error; + } + + if ((result = authsess_xsap_verify(xsap, &digest))) { + free(newIdKey); + goto error; + } + + if (usesAuth == TRUE) { + if ((result = obj_policy_validate_auth_oiap(hSRKPolicy, &digest, &srkAuth))) { + free(newIdKey); + goto error; + } + } + + if ((result = obj_rsakey_set_tcpakey(hIdentityKey, idKeySize, newIdKey))) { + free(newIdKey); + goto error; + } + free(newIdKey); + if ((result = obj_rsakey_set_tcs_handle(hIdentityKey, 0))) + goto error; + + if ((result = obj_rsakey_get_pub_blob(hIdentityKey, &idPubSize, &idPub))) + goto error; + + if ((result = obj_tpm_get_cred(hTPM, TSS_TPMATTRIB_EKCERT, &tempCredSize, &tempCred))) + goto error; + + if (tempCred != NULL) { + free(prgbEndorsementCredential); + prgbEndorsementCredential = tempCred; + pcEndorsementCredentialSize = tempCredSize; + } + + if ((result = obj_tpm_get_cred(hTPM, TSS_TPMATTRIB_TPM_CC, &tempCredSize, &tempCred))) + goto error; + + if (tempCred != NULL) { + free(prgbConformanceCredential); + prgbConformanceCredential = tempCred; + pcConformanceCredentialSize = tempCredSize; + } + + if ((result = obj_tpm_get_cred(hTPM, TSS_TPMATTRIB_PLATFORMCERT, &tempCredSize, &tempCred))) + goto error; + + if (tempCred != NULL) { + free(prgbPlatformCredential); + prgbPlatformCredential = tempCred; + pcPlatformCredentialSize = tempCredSize; + } + + /* set up the TCPA_IDENTITY_PROOF structure */ + /* XXX This should be DER encoded first. TPM1.1b section 9.4 */ + /* XXX hash this incrementally using a Trspi_HashCtx */ + offset = 0; + Trspi_LoadBlob_TSS_VERSION(&offset, hashblob, VERSION_1_1); + Trspi_LoadBlob_UINT32(&offset, ulIdentityLabelLength, hashblob); + Trspi_LoadBlob_UINT32(&offset, pcIdentityBindingSize, hashblob); + Trspi_LoadBlob_UINT32(&offset, pcEndorsementCredentialSize, hashblob); + Trspi_LoadBlob_UINT32(&offset, pcPlatformCredentialSize, hashblob); + Trspi_LoadBlob_UINT32(&offset, pcConformanceCredentialSize, hashblob); + Trspi_LoadBlob(&offset, idPubSize, hashblob, idPub); + free_tspi(tspContext, idPub); + Trspi_LoadBlob(&offset, ulIdentityLabelLength, hashblob, rgbIdentityLabelData); + Trspi_LoadBlob(&offset, pcIdentityBindingSize, hashblob, prgbIdentityBinding); + Trspi_LoadBlob(&offset, pcEndorsementCredentialSize, hashblob, prgbEndorsementCredential); + Trspi_LoadBlob(&offset, pcPlatformCredentialSize, hashblob, prgbPlatformCredential); + Trspi_LoadBlob(&offset, pcConformanceCredentialSize, hashblob, prgbConformanceCredential); + + if (cb && cb->callback) { + /* Alloc the space for the callback to copy into. The additional 32 bytes will + * attempt to account for padding that the symmetric encryption will do. */ + rgbTcpaIdentityReq.asymBlob = calloc(1, (int)offset + 32); + rgbTcpaIdentityReq.symBlob = calloc(1, (int)offset + 32); + if (rgbTcpaIdentityReq.asymBlob == NULL || + rgbTcpaIdentityReq.symBlob == NULL) { + free(rgbTcpaIdentityReq.asymBlob); + free(rgbTcpaIdentityReq.symBlob); + LogError("malloc of %" PRIu64 " bytes failed", offset); + free_tspi(tspContext, cb); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto error; + } + rgbTcpaIdentityReq.asymSize = (UINT32)offset + 32; + rgbTcpaIdentityReq.symSize = (UINT32)offset + 32; + + if ((result = ((TSS_RESULT (*)(PVOID, UINT32, BYTE *, UINT32, UINT32 *, BYTE *, + UINT32 *, BYTE *))cb->callback)(cb->appData, (UINT32)offset, + hashblob, algID, + &rgbTcpaIdentityReq.asymSize, + rgbTcpaIdentityReq.asymBlob, + &rgbTcpaIdentityReq.symSize, + rgbTcpaIdentityReq.symBlob))) { + LogDebug("CollateIdentityRequest callback returned error 0x%x", result); + free_tspi(tspContext, cb); + goto error; + } + } else { + /* generate the symmetric key. */ + if ((result = get_local_random(tspContext, TRUE, symKey.size, &symKey.data))) + goto error; + + /* No symmetric key encryption schemes existed in the 1.1 time frame */ + symKey.encScheme = TCPA_ES_NONE; + + /* encrypt the proof */ + rgbTcpaIdentityReq.symSize = sizeof(testblob); + if ((result = Trspi_SymEncrypt(algID, TR_SYM_MODE_CBC, symKey.data, NULL, hashblob, + offset, testblob, &rgbTcpaIdentityReq.symSize))) + goto error; + + rgbTcpaIdentityReq.symBlob = testblob; + + /* XXX This should be DER encoded first. TPM1.1b section 9.4 */ + offset = 0; + Trspi_LoadBlob_SYMMETRIC_KEY(&offset, hashblob, &symKey); + + if ((result = Trspi_RSA_Public_Encrypt(hashblob, offset, encSymKey, &encSymKeySize, + caKey.pubKey.key, caKey.pubKey.keyLength, + 65537, padding))) + goto error; + + rgbTcpaIdentityReq.asymSize = encSymKeySize; + rgbTcpaIdentityReq.asymBlob = encSymKey; + } + + rgbTcpaIdentityReq.asymAlgorithm = asymParms; + rgbTcpaIdentityReq.symAlgorithm = symParms; + + /* XXX This should be DER encoded first. TPM1.1b section 9.4 */ + offset = 0; + Trspi_LoadBlob_IDENTITY_REQ(&offset, idReqBlob, &rgbTcpaIdentityReq); + + if (cb && cb->callback) { + free(rgbTcpaIdentityReq.symBlob); + free(rgbTcpaIdentityReq.asymBlob); + free_tspi(tspContext, cb); + } + + if ((*prgbTcpaIdentityReq = calloc_tspi(tspContext, offset)) == NULL) { + result = TSPERR(TSS_E_OUTOFMEMORY); + goto error; + } + + memcpy(*prgbTcpaIdentityReq, idReqBlob, offset); + *pulTcpaIdentityReqLength = offset; +error: + authsess_free(xsap); + free_key_refs(&caKey); + free(prgbIdentityBinding); + free(prgbEndorsementCredential); + free(prgbPlatformCredential); + free(prgbConformanceCredential); + + return result; +} + +TSS_RESULT +Tspi_TPM_ActivateIdentity(TSS_HTPM hTPM, /* in */ + TSS_HKEY hIdentKey, /* in */ + UINT32 ulAsymCAContentsBlobLength, /* in */ + BYTE * rgbAsymCAContentsBlob, /* in */ + UINT32 ulSymCAAttestationBlobLength, /* in */ + BYTE * rgbSymCAAttestationBlob, /* in */ + UINT32 * pulCredentialLength, /* out */ + BYTE ** prgbCredential) /* out */ +{ + TPM_AUTH idKeyAuth; + TPM_AUTH ownerAuth; + TSS_HCONTEXT tspContext; + TSS_HPOLICY hIDPolicy, hTPMPolicy; + UINT64 offset; + BYTE credBlob[0x1000]; + TCPA_DIGEST digest; + TSS_RESULT result; + TCS_KEY_HANDLE tcsKeyHandle; + TSS_BOOL usesAuth; + TPM_AUTH *pIDKeyAuth; + BYTE *symKeyBlob, *credCallback, *cb_var; + UINT32 symKeyBlobLen, credLen, tmp; + TCPA_SYMMETRIC_KEY symKey; + TSS_CALLBACK *cb; + Trspi_HashCtx hashCtx; + TPM_SYM_CA_ATTESTATION symCAAttestation; + + if (pulCredentialLength == NULL || prgbCredential == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if ((result = obj_tpm_get_cb12(hTPM, TSS_TSPATTRIB_TPM_CALLBACK_ACTIVATEIDENTITY, &tmp, + &cb_var))) + return result; + + cb = (TSS_CALLBACK *)cb_var; + if (cb->callback == NULL) { + free_tspi(tspContext, cb); + cb = NULL; + } + + if ((result = obj_rsakey_get_tcs_handle(hIdentKey, &tcsKeyHandle))) + return result; + + if ((result = obj_rsakey_get_policy(hIdentKey, TSS_POLICY_USAGE, + &hIDPolicy, &usesAuth))) + return result; + + if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hTPMPolicy))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ActivateIdentity); + result |= Trspi_Hash_UINT32(&hashCtx, ulAsymCAContentsBlobLength); + result |= Trspi_HashUpdate(&hashCtx, ulAsymCAContentsBlobLength, rgbAsymCAContentsBlob); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if (usesAuth) { + if ((result = secret_PerformAuth_OIAP(hIDPolicy, TPM_ORD_ActivateIdentity, + hIDPolicy, FALSE, &digest, &idKeyAuth))) + return result; + pIDKeyAuth = &idKeyAuth; + } else { + pIDKeyAuth = NULL; + } + + if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_ActivateIdentity, hTPMPolicy, FALSE, + &digest, &ownerAuth))) + return result; + + if ((result = TCS_API(tspContext)->ActivateTPMIdentity(tspContext, tcsKeyHandle, + ulAsymCAContentsBlobLength, + rgbAsymCAContentsBlob, pIDKeyAuth, + &ownerAuth, &symKeyBlobLen, + &symKeyBlob))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ActivateIdentity); + result |= Trspi_HashUpdate(&hashCtx, symKeyBlobLen, symKeyBlob); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if (usesAuth) { + if ((result = obj_policy_validate_auth_oiap(hIDPolicy, &digest, + &idKeyAuth))) { + LogDebugFn("Identity key auth validation of the symmetric key failed."); + return result; + } + } + + if ((result = obj_policy_validate_auth_oiap(hTPMPolicy, &digest, + &ownerAuth))) { + LogDebugFn("Owner auth validation of the symmetric key failed."); + return result; + } + + offset = 0; + if ((result = Trspi_UnloadBlob_SYM_CA_ATTESTATION(&offset, rgbSymCAAttestationBlob, + &symCAAttestation))) { + LogDebugFn("Error unloading CA's attestation blob."); + return result; + } + + if (cb && cb->callback) { + /* alloc the space for the callback to copy into */ + credCallback = calloc(1, ulSymCAAttestationBlobLength); + if (credCallback == NULL) { + LogDebug("malloc of %u bytes failed", ulSymCAAttestationBlobLength); + free(symKeyBlob); + free_tspi(tspContext, cb); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + credLen = ulSymCAAttestationBlobLength; + + if ((result = ((TSS_RESULT (*)(PVOID, UINT32, BYTE *, UINT32, BYTE *, UINT32 *, + BYTE *))cb->callback)(cb->appData, symKeyBlobLen, symKeyBlob, + symCAAttestation.credSize, + symCAAttestation.credential, + &credLen, credCallback))) { + LogDebug("ActivateIdentity callback returned error 0x%x", result); + free(symCAAttestation.credential); + free(symKeyBlob); + free_tspi(tspContext, cb); + free(credCallback); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + free(symCAAttestation.credential); + free_tspi(tspContext, cb); + free(symKeyBlob); + + if ((*prgbCredential = calloc_tspi(tspContext, credLen)) == NULL) { + free(credCallback); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + memcpy(*prgbCredential, credCallback, credLen); + *pulCredentialLength = credLen; + free(credCallback); + + return TSS_SUCCESS; + } + + /* decrypt the symmetric blob using the recovered symmetric key */ + offset = 0; + if ((result = Trspi_UnloadBlob_SYMMETRIC_KEY(&offset, symKeyBlob, &symKey))) { + free(symCAAttestation.credential); + free(symKeyBlob); + return result; + } + free(symKeyBlob); + + if ((result = Trspi_SymDecrypt(symKey.algId, symKey.encScheme, symKey.data, NULL, + symCAAttestation.credential, symCAAttestation.credSize, + credBlob, &credLen))) { + free(symCAAttestation.credential); + free(symKey.data); + return result; + } + free(symCAAttestation.credential); + + if ((*prgbCredential = calloc_tspi(tspContext, credLen)) == NULL) { + free(symKey.data); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + free(symKey.data); + memcpy(*prgbCredential, credBlob, credLen); + *pulCredentialLength = credLen; + + return TSS_SUCCESS; +} diff --git a/src/tspi/tspi_asn1.c b/src/tspi/tspi_asn1.c new file mode 100644 index 0000000..f17ce41 --- /dev/null +++ b/src/tspi/tspi_asn1.c @@ -0,0 +1,255 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <openssl/asn1.h> +#include <openssl/asn1t.h> + +#ifndef TSS_BUILD_ASN1_OPENSSL +#include <arpa/inet.h> +#endif + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "tsplog.h" + +#define TSS_OPENSSL_ASN1_ERROR (0xffffffff) + +#if (OPENSSL_VERSION_NUMBER >= 0x0090800FL) +#define OPENSSL_COMPAT_CONST const +#else +#define OPENSSL_COMPAT_CONST +#endif + +#define OPENSSL_COMPAT_ASN1_SEQUENCE(tname) \ + static const ASN1_TEMPLATE tname##_seq_tt[] + +typedef struct tdTSS_BLOB { + ASN1_INTEGER * structVersion; + ASN1_INTEGER * blobType; + ASN1_INTEGER * blobLength; + ASN1_OCTET_STRING * blob; +} TSS_BLOB; + +OPENSSL_COMPAT_ASN1_SEQUENCE(TSS_BLOB) = { + ASN1_SIMPLE(TSS_BLOB, structVersion, ASN1_INTEGER), + ASN1_SIMPLE(TSS_BLOB, blobType, ASN1_INTEGER), + ASN1_SIMPLE(TSS_BLOB, blobLength, ASN1_INTEGER), + ASN1_SIMPLE(TSS_BLOB, blob, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(TSS_BLOB) +IMPLEMENT_ASN1_FUNCTIONS(TSS_BLOB) + + +TSS_RESULT +Tspi_EncodeDER_TssBlob(UINT32 rawBlobSize, /* in */ + BYTE *rawBlob, /* in */ + UINT32 blobType, /* in */ + UINT32 *derBlobSize, /* in/out */ + BYTE *derBlob) /* out */ +{ +#ifdef TSS_BUILD_ASN1_OPENSSL + TSS_BLOB *tssBlob = NULL; +#endif + BYTE *encBlob = NULL; + UINT32 encBlobLen; + + if ((rawBlobSize == 0) || (rawBlob == NULL)) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((blobType < TSS_BLOB_TYPE_KEY) || (blobType > TSS_BLOB_TYPE_CMK_BYTE_STREAM)) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((*derBlobSize != 0) && (derBlob == NULL)) + return TSPERR(TSS_E_BAD_PARAMETER); + + /* The TSS working group has stated that the ASN1 encoding will be done in a + * specific way that generates an ASN1 encoding that is exactly 20 bytes + * larger than the blob being encoded. + * + * OpenSSL uses the smallest number of bytes possible to encode and object + * and as a result cannot be used to perform the encoding. The encoding + * must be done manually. + * + * The 20 byte fixed header will result in issues for objects greater than + * 2^16 in size since some fields are now limited to 16-bit lengths. + */ + +#ifdef TSS_BUILD_ASN1_OPENSSL + tssBlob = TSS_BLOB_new(); + if (!tssBlob) + return TSPERR(TSS_E_OUTOFMEMORY); + + if (ASN1_INTEGER_set(tssBlob->structVersion, TSS_BLOB_STRUCT_VERSION) == 0) { + TSS_BLOB_free(tssBlob); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + if (ASN1_INTEGER_set(tssBlob->blobType, blobType) == 0) { + TSS_BLOB_free(tssBlob); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + if (ASN1_INTEGER_set(tssBlob->blobLength, rawBlobSize) == 0) { + TSS_BLOB_free(tssBlob); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + if (ASN1_OCTET_STRING_set(tssBlob->blob, rawBlob, rawBlobSize) == 0) { + TSS_BLOB_free(tssBlob); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + encBlobLen = i2d_TSS_BLOB(tssBlob, &encBlob); + if (encBlobLen <= 0) { + TSS_BLOB_free(tssBlob); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + if (*derBlobSize != 0) { + if (encBlobLen <= *derBlobSize) { + memcpy(derBlob, encBlob, encBlobLen); + } + else { + OPENSSL_free(encBlob); + TSS_BLOB_free(tssBlob); + return TSPERR(TSS_E_BAD_PARAMETER); + } + } + + *derBlobSize = encBlobLen; + + OPENSSL_free(encBlob); + TSS_BLOB_free(tssBlob); +#else + if ((rawBlobSize + 16) > UINT16_MAX) + return TSPERR(TSS_E_INTERNAL_ERROR); + + encBlobLen = rawBlobSize + 20; + + if (*derBlobSize != 0) { + if (encBlobLen <= *derBlobSize) { + UINT16 *pShort; + UINT32 *pLong; + + encBlob = derBlob; + encBlob[0] = 0x30; /* Sequence tag */ + encBlob[1] = 0x82; /* Length in the two octets that follow */ + encBlob += 2; + pShort = (UINT16 *)encBlob; + *pShort = htons(rawBlobSize + 16); + encBlob += sizeof(UINT16); + + encBlob[0] = 0x02; /* Integer tag */ + encBlob[1] = 0x01; /* Length is one */ + encBlob[2] = (BYTE)TSS_BLOB_STRUCT_VERSION; + encBlob += 3; + + encBlob[0] = 0x02; /* Integer tag */ + encBlob[1] = 0x01; /* Length is one */ + encBlob[2] = (BYTE)blobType; + encBlob += 3; + + encBlob[0] = 0x02; /* Integer tag */ + encBlob[1] = 0x04; /* Length is four */ + encBlob += 2; + pLong = (UINT32 *)encBlob; + *pLong = htonl(rawBlobSize); + encBlob += sizeof(UINT32); + + encBlob[0] = 0x04; /* Octet string tag */ + encBlob[1] = 0x82; /* Length in the two octets that follow */ + encBlob += 2; + pShort = (UINT16 *)encBlob; + *pShort = htons(rawBlobSize); + encBlob += sizeof(UINT16); + memcpy(encBlob, rawBlob, rawBlobSize); + } + else + return TSPERR(TSS_E_BAD_PARAMETER); + } + + *derBlobSize = encBlobLen; +#endif + + return TSS_SUCCESS; +} + +TSS_RESULT +Tspi_DecodeBER_TssBlob(UINT32 berBlobSize, /* in */ + BYTE *berBlob, /* in */ + UINT32 *blobType, /* out */ + UINT32 *rawBlobSize, /* in/out */ + BYTE *rawBlob) /* out */ +{ + TSS_BLOB *tssBlob = NULL; + OPENSSL_COMPAT_CONST BYTE *encBlob = berBlob; + + UINT32 encBlobLen = berBlobSize; + UINT32 decStructVersion, decBlobType, decBlobSize; + + if ((berBlobSize == 0) || (berBlob == NULL)) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((*rawBlobSize != 0) && (rawBlob == NULL)) + return TSPERR(TSS_E_BAD_PARAMETER); + + tssBlob = d2i_TSS_BLOB(NULL, &encBlob, encBlobLen); + if (!tssBlob) + return TSPERR(TSS_E_INTERNAL_ERROR); + + decStructVersion = ASN1_INTEGER_get(tssBlob->structVersion); + if (decStructVersion == TSS_OPENSSL_ASN1_ERROR) { + TSS_BLOB_free(tssBlob); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if (decStructVersion > TSS_BLOB_STRUCT_VERSION) { + TSS_BLOB_free(tssBlob); + return TSPERR(TSS_E_BAD_PARAMETER); + } + + decBlobType = ASN1_INTEGER_get(tssBlob->blobType); + if (decBlobType == TSS_OPENSSL_ASN1_ERROR) { + TSS_BLOB_free(tssBlob); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + if ((decBlobType < TSS_BLOB_TYPE_KEY) || (decBlobType > TSS_BLOB_TYPE_CMK_BYTE_STREAM)) { + TSS_BLOB_free(tssBlob); + return TSPERR(TSS_E_BAD_PARAMETER); + } + + decBlobSize = ASN1_INTEGER_get(tssBlob->blobLength); + if (decBlobSize == TSS_OPENSSL_ASN1_ERROR) { + TSS_BLOB_free(tssBlob); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + if (*rawBlobSize != 0) { + if (decBlobSize <= *rawBlobSize) { + memcpy(rawBlob, tssBlob->blob->data, decBlobSize); + } + else { + TSS_BLOB_free(tssBlob); + return TSPERR(TSS_E_BAD_PARAMETER); + } + } + + *rawBlobSize = decBlobSize; + *blobType = decBlobType; + + TSS_BLOB_free(tssBlob); + + return TSS_SUCCESS; +} + diff --git a/src/tspi/tspi_audit.c b/src/tspi/tspi_audit.c new file mode 100644 index 0000000..1c13ca1 --- /dev/null +++ b/src/tspi/tspi_audit.c @@ -0,0 +1,313 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "obj.h" +#include "tsplog.h" + + +/* XXX Split into two functions */ +TSS_RESULT +Tspi_TPM_GetAuditDigest(TSS_HTPM hTpm, /* in */ + TSS_HKEY hKey, /* in */ + TSS_BOOL closeAudit, /* in */ + UINT32* pulAuditDigestSize, /* out */ + BYTE** prgbAuditDigest, /* out */ + TPM_COUNTER_VALUE* pCounterValue, /* out */ + TSS_VALIDATION* pValidationData, /* out */ + UINT32* ordSize, /* out */ + UINT32** ordList) /* out */ +{ + TSS_HCONTEXT tspContext; + UINT32 counterValueSize; + BYTE *counterValue = NULL; + TPM_DIGEST auditDigest; + TSS_RESULT result = TSS_SUCCESS; + UINT64 offset; + + if ((pulAuditDigestSize == NULL) || (prgbAuditDigest == NULL) || (pCounterValue == NULL)) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (hKey == NULL_HKEY) + if ((ordSize == NULL) || (ordList == NULL)) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTpm, &tspContext))) + return result; + + if (hKey == NULL_HKEY) { + UINT32 startOrdinal = 0; + TSS_BOOL more; + UINT32 tcsOrdSize; + UINT32 *tcsOrdList = NULL; + UINT32 *pulTemp; + + *prgbAuditDigest = NULL; + *pulAuditDigestSize = 0; + *ordList = NULL; + *ordSize = 0; + do { + if ((result = TCS_API(tspContext)->GetAuditDigest(tspContext, startOrdinal, + &auditDigest, + &counterValueSize, + &counterValue, &more, + &tcsOrdSize, + &tcsOrdList))) + goto done1; + + if ((pulTemp = + calloc_tspi(tspContext, + (*ordSize + tcsOrdSize) * sizeof(UINT32))) == NULL) { + LogError("malloc of %u bytes failed.", *ordSize + tcsOrdSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done1; + } + + if (*ordList) + memcpy(pulTemp, *ordList, *ordSize * sizeof(UINT32)); + memcpy(pulTemp + *ordSize, tcsOrdList, tcsOrdSize * sizeof(UINT32)); + + free(tcsOrdList); + tcsOrdList = NULL; + + if (*ordList) + free_tspi(tspContext, *ordList); + *ordList = pulTemp; + *ordSize += tcsOrdSize; + + if (more == TRUE) { + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, &startOrdinal, + (BYTE *)(*ordList + (*ordSize - 1))); + startOrdinal++; + free(counterValue); + counterValue = NULL; + } + } while (more == TRUE); + + *pulAuditDigestSize = sizeof(auditDigest.digest); + if ((*prgbAuditDigest = calloc_tspi(tspContext, *pulAuditDigestSize)) == NULL) { + LogError("malloc of %u bytes failed.", *pulAuditDigestSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done1; + } + offset = 0; + Trspi_LoadBlob_DIGEST(&offset, *prgbAuditDigest, &auditDigest); + + offset = 0; + Trspi_UnloadBlob_COUNTER_VALUE(&offset, counterValue, pCounterValue); + + result = TSS_SUCCESS; + +done1: + if (result != TSS_SUCCESS) { + if (*prgbAuditDigest) + free_tspi(tspContext, *prgbAuditDigest); + if (*ordList) + free_tspi(tspContext, *ordList); + *prgbAuditDigest = NULL; + *pulAuditDigestSize = 0; + *ordList = NULL; + *ordSize = 0; + } + free(counterValue); + free(tcsOrdList); + + return result; + } + else { + TSS_HPOLICY hPolicy; + TSS_BOOL usesAuth; + TCS_KEY_HANDLE tcsKeyHandle; + TPM_AUTH keyAuth, *pAuth; + Trspi_HashCtx hashCtx; + TCPA_DIGEST digest; + TPM_NONCE antiReplay; + TPM_DIGEST auditDigest; + TPM_DIGEST ordinalDigest; + UINT32 sigSize; + BYTE *sig = NULL; + TPM_SIGN_INFO signInfo; + UINT32 signInfoBlobSize; + BYTE *signInfoBlob = NULL; + + if (pValidationData == NULL) { + LogDebug("Internal Verify"); + if ((result = get_local_random(tspContext, FALSE, TPM_NONCE_SIZE, + (BYTE **)antiReplay.nonce))) + return result; + } else { + LogDebug("External Verify"); + if (pValidationData->ulExternalDataLength < sizeof(antiReplay.nonce)) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (pValidationData->rgbExternalData == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + memcpy(antiReplay.nonce, pValidationData->rgbExternalData, + sizeof(antiReplay.nonce)); + + pValidationData->ulDataLength = 0; + pValidationData->rgbData = NULL; + pValidationData->ulValidationDataLength = 0; + pValidationData->rgbValidationData = NULL; + } + + if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth))) + return result; + + if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle))) + return result; + + if (usesAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_GetAuditDigestSigned); + result |= Trspi_Hash_BOOL(&hashCtx, closeAudit); + result |= Trspi_Hash_NONCE(&hashCtx, antiReplay.nonce); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + pAuth = &keyAuth; + if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_GetAuditDigestSigned, + hPolicy, FALSE, &digest, pAuth))) + return result; + } + else + pAuth = NULL; + + if ((result = TCS_API(tspContext)->GetAuditDigestSigned(tspContext, tcsKeyHandle, + closeAudit, &antiReplay, + pAuth, &counterValueSize, + &counterValue, &auditDigest, + &ordinalDigest, &sigSize, + &sig))) + return result; + + memset(&signInfo, 0, sizeof(signInfo)); + signInfo.tag = TPM_TAG_SIGNINFO; + memcpy(signInfo.fixed, "ADIG", strlen("ADIG")); + signInfo.replay = antiReplay; + signInfo.dataLen = sizeof(auditDigest.digest) + counterValueSize + + sizeof(ordinalDigest.digest); + if ((signInfo.data = malloc(signInfo.dataLen)) == NULL) { + LogError("malloc of %u bytes failed.", signInfo.dataLen); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done2; + } + offset = 0; + Trspi_LoadBlob_DIGEST(&offset, signInfo.data, &auditDigest); + Trspi_LoadBlob(&offset, counterValueSize, signInfo.data, counterValue); + Trspi_LoadBlob_DIGEST(&offset, signInfo.data, &ordinalDigest); + + if (usesAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_GetAuditDigestSigned); + result |= Trspi_HashUpdate(&hashCtx, counterValueSize, counterValue); + result |= Trspi_Hash_DIGEST(&hashCtx, auditDigest.digest); + result |= Trspi_Hash_DIGEST(&hashCtx, ordinalDigest.digest); + result |= Trspi_Hash_UINT32(&hashCtx, sigSize); + result |= Trspi_HashUpdate(&hashCtx, sigSize, sig); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done2; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth))) + goto done2; + } + + offset = 0; + Trspi_LoadBlob_SIGN_INFO(&offset, NULL, &signInfo); + signInfoBlobSize = offset; + signInfoBlob = malloc(signInfoBlobSize); + if (signInfoBlob == NULL) { + LogError("malloc of %u bytes failed.", signInfoBlobSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done2; + } + offset = 0; + Trspi_LoadBlob_SIGN_INFO(&offset, signInfoBlob, &signInfo); + + if (pValidationData == NULL) { + if ((result = Trspi_Hash(TSS_HASH_SHA1, signInfoBlobSize, signInfoBlob, + digest.digest))) + goto done2; + + if ((result = __tspi_rsa_verify(hKey, TSS_HASH_SHA1, sizeof(digest.digest), + digest.digest, sigSize, sig))) { + result = TSPERR(TSS_E_VERIFICATION_FAILED); + goto done2; + } + } else { + pValidationData->ulDataLength = signInfoBlobSize; + pValidationData->rgbData = calloc_tspi(tspContext, signInfoBlobSize); + if (pValidationData->rgbData == NULL) { + LogError("malloc of %u bytes failed.", signInfoBlobSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done2; + } + memcpy(pValidationData->rgbData, signInfoBlob, signInfoBlobSize); + + pValidationData->ulValidationDataLength = sigSize; + pValidationData->rgbValidationData = calloc_tspi(tspContext, sigSize); + if (pValidationData->rgbValidationData == NULL) { + LogError("malloc of %u bytes failed.", sigSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done2; + } + memcpy(pValidationData->rgbValidationData, sig, sigSize); + } + + *pulAuditDigestSize = sizeof(auditDigest.digest); + if ((*prgbAuditDigest = calloc_tspi(tspContext, *pulAuditDigestSize)) == NULL) { + LogError("malloc of %u bytes failed.", *pulAuditDigestSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done2; + } + offset = 0; + Trspi_LoadBlob_DIGEST(&offset, *prgbAuditDigest, &auditDigest); + + offset = 0; + Trspi_UnloadBlob_COUNTER_VALUE(&offset, counterValue, pCounterValue); + + result = TSS_SUCCESS; + +done2: + if (result != TSS_SUCCESS) { + if (*prgbAuditDigest) + free_tspi(tspContext, *prgbAuditDigest); + *prgbAuditDigest = NULL; + *pulAuditDigestSize = 0; + if (pValidationData != NULL) { + if (pValidationData->rgbData) + free_tspi(tspContext, pValidationData->rgbData); + if (pValidationData->rgbValidationData) + free_tspi(tspContext, pValidationData->rgbValidationData); + pValidationData->ulDataLength = 0; + pValidationData->rgbData = NULL; + pValidationData->ulValidationDataLength = 0; + pValidationData->rgbValidationData = NULL; + } + } + free(counterValue); + free(sig); + free(signInfo.data); + free(signInfoBlob); + + return result; + } +} diff --git a/src/tspi/tspi_bind.c b/src/tspi/tspi_bind.c new file mode 100644 index 0000000..ae9a8ba --- /dev/null +++ b/src/tspi/tspi_bind.c @@ -0,0 +1,217 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_Data_Bind(TSS_HENCDATA hEncData, /* in */ + TSS_HKEY hEncKey, /* in */ + UINT32 ulDataLength, /* in */ + BYTE *rgbDataToBind) /* in */ +{ + UINT32 encDataLength; + BYTE encData[256]; + BYTE *keyData; + UINT32 keyDataLength; + TCPA_BOUND_DATA boundData; + UINT64 offset; + BYTE bdblob[256]; + TCPA_RESULT result; + TSS_KEY keyContainer; + TSS_HCONTEXT tspContext; + + if (rgbDataToBind == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (!obj_is_encdata(hEncData)) + return TSPERR(TSS_E_INVALID_HANDLE); + + if ((result = obj_rsakey_get_tsp_context(hEncKey, &tspContext))) + return result; + + /* XXX Just get the pubkey here */ + if ((result = obj_rsakey_get_blob(hEncKey, &keyDataLength, &keyData))) + return result; + + offset = 0; + if ((result = UnloadBlob_TSS_KEY(&offset, keyData, &keyContainer))) { + free_tspi(tspContext, keyData); + return result; + } + free_tspi(tspContext, keyData); + + if (keyContainer.keyUsage != TPM_KEY_BIND && + keyContainer.keyUsage != TPM_KEY_LEGACY) { + result = TSPERR(TSS_E_INVALID_KEYUSAGE); + goto done; + } + + if (keyContainer.pubKey.keyLength < ulDataLength) { + result = TSPERR(TSS_E_ENC_INVALID_LENGTH); + goto done; + } + + if (keyContainer.algorithmParms.encScheme == TCPA_ES_RSAESPKCSv15 && + keyContainer.keyUsage == TPM_KEY_LEGACY) { + if ((result = Trspi_RSA_PKCS15_Encrypt(rgbDataToBind, ulDataLength, encData, + &encDataLength, keyContainer.pubKey.key, + keyContainer.pubKey.keyLength))) + goto done; + } else if (keyContainer.algorithmParms.encScheme == TCPA_ES_RSAESPKCSv15 && + keyContainer.keyUsage == TPM_KEY_BIND) { + boundData.payload = TCPA_PT_BIND; + + memcpy(&boundData.ver, &VERSION_1_1, sizeof(TCPA_VERSION)); + + boundData.payloadData = malloc(ulDataLength); + if (boundData.payloadData == NULL) { + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(boundData.payloadData, rgbDataToBind, ulDataLength); + + offset = 0; + Trspi_LoadBlob_BOUND_DATA(&offset, boundData, ulDataLength, bdblob); + + if ((result = Trspi_RSA_PKCS15_Encrypt(bdblob, offset, encData, + &encDataLength, keyContainer.pubKey.key, + keyContainer.pubKey.keyLength))) { + free(boundData.payloadData); + goto done; + } + free(boundData.payloadData); + } else { + boundData.payload = TCPA_PT_BIND; + + memcpy(&boundData.ver, &VERSION_1_1, sizeof(TCPA_VERSION)); + + boundData.payloadData = malloc(ulDataLength); + if (boundData.payloadData == NULL) { + LogError("malloc of %u bytes failed.", ulDataLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(boundData.payloadData, rgbDataToBind, ulDataLength); + + offset = 0; + Trspi_LoadBlob_BOUND_DATA(&offset, boundData, ulDataLength, bdblob); + + if ((result = Trspi_RSA_Encrypt(bdblob, offset, encData, &encDataLength, + keyContainer.pubKey.key, + keyContainer.pubKey.keyLength))) { + free(boundData.payloadData); + goto done; + } + + free(boundData.payloadData); + } + + if ((result = obj_encdata_set_data(hEncData, encDataLength, encData))) { + LogError("Error in calling SetAttribData on the encrypted data object."); + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto done; + } +done: + free_key_refs(&keyContainer); + return result; +} + +TSS_RESULT +Tspi_Data_Unbind(TSS_HENCDATA hEncData, /* in */ + TSS_HKEY hKey, /* in */ + UINT32 * pulUnboundDataLength, /* out */ + BYTE ** prgbUnboundData) /* out */ +{ + TCPA_RESULT result; + TPM_AUTH privAuth; + TCPA_DIGEST digest; + TSS_HPOLICY hPolicy; + BYTE *encData; + UINT32 encDataSize; + TCS_KEY_HANDLE tcsKeyHandle; + TSS_BOOL usesAuth; + TPM_AUTH *pPrivAuth; + TSS_HCONTEXT tspContext; + Trspi_HashCtx hashCtx; + + if (pulUnboundDataLength == NULL || prgbUnboundData == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_encdata_get_tsp_context(hEncData, &tspContext))) + return result; + + if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth))) + return result; + + if ((result = obj_encdata_get_data(hEncData, &encDataSize, &encData))) + return result == (TSS_E_INVALID_OBJ_ACCESS | TSS_LAYER_TSP) ? + TSPERR(TSS_E_ENC_NO_DATA) : + result; + + if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle))) + return result; + + if (usesAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_UnBind); + result |= Trspi_Hash_UINT32(&hashCtx, encDataSize); + result |= Trspi_HashUpdate(&hashCtx, encDataSize, encData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_UnBind, hPolicy, FALSE, &digest, + &privAuth))) + return result; + pPrivAuth = &privAuth; + } else { + pPrivAuth = NULL; + } + + if ((result = TCS_API(tspContext)->UnBind(tspContext, tcsKeyHandle, encDataSize, encData, + pPrivAuth, pulUnboundDataLength, + prgbUnboundData))) + return result; + + if (usesAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_UnBind); + result |= Trspi_Hash_UINT32(&hashCtx, *pulUnboundDataLength); + result |= Trspi_HashUpdate(&hashCtx, *pulUnboundDataLength, *prgbUnboundData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &privAuth))) + goto error; + } + + if ((result = __tspi_add_mem_entry(tspContext, *prgbUnboundData))) + goto error; + + return TSS_SUCCESS; +error: + free(*prgbUnboundData); + *prgbUnboundData = NULL; + *pulUnboundDataLength = 0; + return result; +} + diff --git a/src/tspi/tspi_caps.c b/src/tspi/tspi_caps.c new file mode 100644 index 0000000..2997d8d --- /dev/null +++ b/src/tspi/tspi_caps.c @@ -0,0 +1,87 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "tcs_tsp.h" +#include "tspps.h" +#include "tcsd_wrap.h" +#include "tcsd.h" +#include "obj.h" + + +TSS_RESULT +Tspi_Context_GetCapability(TSS_HCONTEXT tspContext, /* in */ + TSS_FLAG capArea, /* in */ + UINT32 ulSubCapLength, /* in */ + BYTE * rgbSubCap, /* in */ + UINT32 * pulRespDataLength, /* out */ + BYTE ** prgbRespData) /* out */ +{ + TSS_RESULT result; + + if (prgbRespData == NULL || pulRespDataLength == NULL ) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (rgbSubCap == NULL && ulSubCapLength != 0) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (ulSubCapLength > sizeof(UINT32)) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (!obj_is_context(tspContext)) + return TSPERR(TSS_E_INVALID_HANDLE); + + switch (capArea) { + case TSS_TSPCAP_ALG: + case TSS_TSPCAP_RETURNVALUE_INFO: + case TSS_TSPCAP_PLATFORM_INFO: + case TSS_TSPCAP_MANUFACTURER: + if (ulSubCapLength != sizeof(UINT32) || !rgbSubCap) + return TSPERR(TSS_E_BAD_PARAMETER); + /* fall through */ + case TSS_TSPCAP_VERSION: + case TSS_TSPCAP_PERSSTORAGE: + result = internal_GetCap(tspContext, capArea, + rgbSubCap ? *(UINT32 *)rgbSubCap : 0, + pulRespDataLength, + prgbRespData); + break; + case TSS_TCSCAP_ALG: + if (ulSubCapLength != sizeof(UINT32) || !rgbSubCap) + return TSPERR(TSS_E_BAD_PARAMETER); + /* fall through */ + case TSS_TCSCAP_VERSION: + case TSS_TCSCAP_CACHING: + case TSS_TCSCAP_PERSSTORAGE: + case TSS_TCSCAP_MANUFACTURER: + case TSS_TCSCAP_TRANSPORT: + case TSS_TCSCAP_PLATFORM_CLASS: + result = RPC_GetCapability(tspContext, capArea, ulSubCapLength, rgbSubCap, + pulRespDataLength, prgbRespData); + break; + default: + LogDebug("Invalid capArea: 0x%x", capArea); + result = TSPERR(TSS_E_BAD_PARAMETER); + break; + } + + return result; +} diff --git a/src/tspi/tspi_caps_tpm.c b/src/tspi/tspi_caps_tpm.c new file mode 100644 index 0000000..131e67b --- /dev/null +++ b/src/tspi/tspi_caps_tpm.c @@ -0,0 +1,356 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_TPM_GetCapability(TSS_HTPM hTPM, /* in */ + TSS_FLAG capArea, /* in */ + UINT32 ulSubCapLength, /* in */ + BYTE * rgbSubCap, /* in */ + UINT32 * pulRespDataLength, /* out */ + BYTE ** prgbRespData) /* out */ +{ + TSS_HCONTEXT tspContext; + TPM_CAPABILITY_AREA tcsCapArea; + UINT32 tcsSubCap = 0; + UINT32 tcsSubCapContainer; + TSS_RESULT result; + UINT32 nonVolFlags, volFlags, respLen; + BYTE *respData; + UINT64 offset; + TSS_BOOL fOwnerAuth = FALSE, endianFlag = TRUE; + + if (pulRespDataLength == NULL || prgbRespData == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + /* Verify the caps and subcaps */ + switch (capArea) { + case TSS_TPMCAP_ORD: + if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) + return TSPERR(TSS_E_BAD_PARAMETER); + + tcsCapArea = TCPA_CAP_ORD; + tcsSubCap = *(UINT32 *)rgbSubCap; + break; + case TSS_TPMCAP_FLAG: + fOwnerAuth = TRUE; + break; + case TSS_TPMCAP_AUTH_ENCRYPT: + case TSS_TPMCAP_ALG: + if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) + return TSPERR(TSS_E_BAD_PARAMETER); + + /* Test capArea again here in order to keep from having to duplicate the switch + * statement below */ + tcsCapArea = (capArea == TSS_TPMCAP_ALG ? TPM_CAP_ALG : TPM_CAP_AUTH_ENCRYPT); + + switch (*(UINT32 *)rgbSubCap) { + case TSS_ALG_RSA: + tcsSubCap = TPM_ALG_RSA; + break; + case TSS_ALG_AES128: + tcsSubCap = TPM_ALG_AES128; + break; + case TSS_ALG_AES192: + tcsSubCap = TPM_ALG_AES192; + break; + case TSS_ALG_AES256: + tcsSubCap = TPM_ALG_AES256; + break; + case TSS_ALG_3DES: + tcsSubCap = TPM_ALG_3DES; + break; + case TSS_ALG_DES: + tcsSubCap = TPM_ALG_DES; + break; + case TSS_ALG_SHA: + tcsSubCap = TPM_ALG_SHA; + break; + case TSS_ALG_HMAC: + tcsSubCap = TPM_ALG_HMAC; + break; + case TSS_ALG_MGF1: + tcsSubCap = TPM_ALG_MGF1; + break; + case TSS_ALG_XOR: + tcsSubCap = TPM_ALG_XOR; + break; + default: + tcsSubCap = *(UINT32 *)rgbSubCap; + break; + } + break; +#ifdef TSS_BUILD_NV + case TSS_TPMCAP_NV_LIST: + tcsCapArea = TPM_CAP_NV_LIST; + endianFlag = FALSE; + break; + case TSS_TPMCAP_NV_INDEX: + if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) + return TSPERR(TSS_E_BAD_PARAMETER); + + tcsCapArea = TPM_CAP_NV_INDEX; + tcsSubCap = *(UINT32 *)rgbSubCap; + break; +#endif + case TSS_TPMCAP_PROPERTY: /* Determines a physical property of the TPM. */ + if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) + return TSPERR(TSS_E_BAD_PARAMETER); + + tcsCapArea = TCPA_CAP_PROPERTY; + tcsSubCapContainer = *(UINT32 *)rgbSubCap; + + switch (tcsSubCapContainer) { + case TSS_TPMCAP_PROP_PCR: + tcsSubCap = TPM_CAP_PROP_PCR; + break; + case TSS_TPMCAP_PROP_DIR: + tcsSubCap = TPM_CAP_PROP_DIR; + break; + /* case TSS_TPMCAP_PROP_SLOTS: */ + case TSS_TPMCAP_PROP_KEYS: + tcsSubCap = TPM_CAP_PROP_SLOTS; + break; + case TSS_TPMCAP_PROP_MANUFACTURER: + tcsSubCap = TPM_CAP_PROP_MANUFACTURER; + endianFlag = FALSE; + break; + case TSS_TPMCAP_PROP_COUNTERS: + tcsSubCap = TPM_CAP_PROP_COUNTERS; + break; + case TSS_TPMCAP_PROP_MAXCOUNTERS: + tcsSubCap = TPM_CAP_PROP_MAX_COUNTERS; + break; + /*case TSS_TPMCAP_PROP_MINCOUNTERINCTIME: */ + case TSS_TPMCAP_PROP_MIN_COUNTER: + tcsSubCap = TPM_CAP_PROP_MIN_COUNTER; + break; + case TSS_TPMCAP_PROP_ACTIVECOUNTER: + tcsSubCap = TPM_CAP_PROP_ACTIVE_COUNTER; + break; + case TSS_TPMCAP_PROP_TRANSESSIONS: + tcsSubCap = TPM_CAP_PROP_TRANSSESS; + break; + case TSS_TPMCAP_PROP_MAXTRANSESSIONS: + tcsSubCap = TPM_CAP_PROP_MAX_TRANSSESS; + break; + case TSS_TPMCAP_PROP_SESSIONS: + tcsSubCap = TPM_CAP_PROP_SESSIONS; + break; + case TSS_TPMCAP_PROP_MAXSESSIONS: + tcsSubCap = TPM_CAP_PROP_MAX_SESSIONS; + break; + case TSS_TPMCAP_PROP_FAMILYROWS: + tcsSubCap = TPM_CAP_PROP_FAMILYROWS; + break; + case TSS_TPMCAP_PROP_DELEGATEROWS: + tcsSubCap = TPM_CAP_PROP_DELEGATE_ROW; + break; + case TSS_TPMCAP_PROP_OWNER: + tcsSubCap = TPM_CAP_PROP_OWNER; + break; + case TSS_TPMCAP_PROP_MAXKEYS: + tcsSubCap = TPM_CAP_PROP_MAX_KEYS; + break; + case TSS_TPMCAP_PROP_AUTHSESSIONS: + tcsSubCap = TPM_CAP_PROP_AUTHSESS; + break; + case TSS_TPMCAP_PROP_MAXAUTHSESSIONS: + tcsSubCap = TPM_CAP_PROP_MAX_AUTHSESS; + break; + case TSS_TPMCAP_PROP_CONTEXTS: + tcsSubCap = TPM_CAP_PROP_CONTEXT; + break; + case TSS_TPMCAP_PROP_MAXCONTEXTS: + tcsSubCap = TPM_CAP_PROP_MAX_CONTEXT; + break; + case TSS_TPMCAP_PROP_DAASESSIONS: + tcsSubCap = TPM_CAP_PROP_SESSION_DAA; + break; + case TSS_TPMCAP_PROP_MAXDAASESSIONS: + tcsSubCap = TPM_CAP_PROP_DAA_MAX; + break; + case TSS_TPMCAP_PROP_TISTIMEOUTS: + tcsSubCap = TPM_CAP_PROP_TIS_TIMEOUT; + break; + case TSS_TPMCAP_PROP_STARTUPEFFECTS: + tcsSubCap = TPM_CAP_PROP_STARTUP_EFFECT; + endianFlag = FALSE; + break; + case TSS_TPMCAP_PROP_MAXCONTEXTCOUNTDIST: + tcsSubCap = TPM_CAP_PROP_CONTEXT_DIST; + break; + case TSS_TPMCAP_PROP_CMKRESTRICTION: + tcsSubCap = TPM_CAP_PROP_CMK_RESTRICTION; + break; + case TSS_TPMCAP_PROP_DURATION: + tcsSubCap = TPM_CAP_PROP_DURATION; + break; + case TSS_TPMCAP_PROP_MAXNVAVAILABLE: + tcsSubCap = TPM_CAP_PROP_NV_AVAILABLE; + break; + case TSS_TPMCAP_PROP_INPUTBUFFERSIZE: + tcsSubCap = TPM_CAP_PROP_INPUT_BUFFER; + break; +#if 0 + /* There isn't a way to query the TPM for these, the TPMWG is considering how to + * address some of them in the next version of the TPM - KEY Oct 15, 2007*/ + case TSS_TPMCAP_PROP_MAXNVWRITE: + break; + case TSS_TPMCAP_PROP_REVISION: + break; + case TSS_TPMCAP_PROP_LOCALITIES_AVAIL: + break; + case TSS_TPMCAP_PROP_PCRMAP: + break; +#endif + default: + return TSPERR(TSS_E_BAD_PARAMETER); + } + break; + case TSS_TPMCAP_VERSION: /* Queries the current TPM version. */ + tcsCapArea = TCPA_CAP_VERSION; + endianFlag = FALSE; + break; + case TSS_TPMCAP_VERSION_VAL: /* Queries the current TPM version for 1.2 TPM device. */ + tcsCapArea = TPM_CAP_VERSION_VAL; + endianFlag = FALSE; + break; + case TSS_TPMCAP_MFR: + tcsCapArea = TPM_CAP_MFR; + endianFlag = FALSE; + break; + case TSS_TPMCAP_SYM_MODE: + if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) + return TSPERR(TSS_E_BAD_PARAMETER); + + tcsCapArea = TPM_CAP_SYM_MODE; + tcsSubCap = *(UINT32 *)rgbSubCap; + break; + case TSS_TPMCAP_HANDLE: + if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) + return TSPERR(TSS_E_BAD_PARAMETER); + + tcsCapArea = TPM_CAP_HANDLE; + tcsSubCap = *(UINT32 *)rgbSubCap; + break; + case TSS_TPMCAP_TRANS_ES: + if ((ulSubCapLength != sizeof(UINT32)) || !rgbSubCap) + return TSPERR(TSS_E_BAD_PARAMETER); + + tcsCapArea = TPM_CAP_TRANS_ES; + switch (*(UINT32 *)rgbSubCap) { + case TSS_ES_NONE: + tcsSubCap = TPM_ES_NONE; + break; + case TSS_ES_RSAESPKCSV15: + tcsSubCap = TPM_ES_RSAESPKCSv15; + break; + case TSS_ES_RSAESOAEP_SHA1_MGF1: + tcsSubCap = TPM_ES_RSAESOAEP_SHA1_MGF1; + break; + case TSS_ES_SYM_CNT: + tcsSubCap = TPM_ES_SYM_CNT; + break; + case TSS_ES_SYM_OFB: + tcsSubCap = TPM_ES_SYM_OFB; + break; + case TSS_ES_SYM_CBC_PKCS5PAD: + tcsSubCap = TPM_ES_SYM_CBC_PKCS5PAD; + break; + default: + tcsSubCap = *(UINT32 *)rgbSubCap; + break; + } + break; + default: + return TSPERR(TSS_E_BAD_PARAMETER); + break; + } + + if (fOwnerAuth) { + /* do an owner authorized get capability call */ + if ((result = get_tpm_flags(tspContext, hTPM, &volFlags, &nonVolFlags))) + return result; + + respLen = 2 * sizeof(UINT32); + respData = calloc_tspi(tspContext, respLen); + if (respData == NULL) { + LogError("malloc of %u bytes failed.", respLen); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + offset = 0; + Trspi_LoadBlob_UINT32(&offset, nonVolFlags, respData); + Trspi_LoadBlob_UINT32(&offset, volFlags, respData); + + *pulRespDataLength = respLen; + *prgbRespData = respData; + + return TSS_SUCCESS; + } + + tcsSubCap = endian32(tcsSubCap); + + if ((result = TCS_API(tspContext)->GetTPMCapability(tspContext, tcsCapArea, ulSubCapLength, + (BYTE *)&tcsSubCap, pulRespDataLength, + prgbRespData))) + return result; + + if (endianFlag) { + if (*pulRespDataLength == sizeof(UINT32)) + *(UINT32 *)(*prgbRespData) = endian32(*(UINT32 *)(*prgbRespData)); + else if (*pulRespDataLength == sizeof(UINT16)) + *(UINT32 *)(*prgbRespData) = endian16(*(UINT32 *)(*prgbRespData)); + } + + if ((result = __tspi_add_mem_entry(tspContext, *prgbRespData))) { + free(*prgbRespData); + *prgbRespData = NULL; + *pulRespDataLength = 0; + return result; + } + + return TSS_SUCCESS; +} + +TSS_RESULT +Tspi_TPM_GetCapabilitySigned(TSS_HTPM hTPM, /* in */ + TSS_HTPM hKey, /* in */ + TSS_FLAG capArea, /* in */ + UINT32 ulSubCapLength, /* in */ + BYTE * rgbSubCap, /* in */ + TSS_VALIDATION * pValidationData, /* in, out */ + UINT32 * pulRespDataLength, /* out */ + BYTE ** prgbRespData) /* out */ +{ + /* + * Function was found to have a vulnerability, so implementation is not + * required by the TSS 1.1b spec. + */ + return TSPERR(TSS_E_NOTIMPL); +} + diff --git a/src/tspi/tspi_certify.c b/src/tspi/tspi_certify.c new file mode 100644 index 0000000..795d2d4 --- /dev/null +++ b/src/tspi/tspi_certify.c @@ -0,0 +1,164 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_Key_CertifyKey(TSS_HKEY hKey, /* in */ + TSS_HKEY hCertifyingKey, /* in */ + TSS_VALIDATION * pValidationData) /* in, out */ +{ + TCPA_RESULT result; + TPM_AUTH certAuth; + TPM_AUTH keyAuth; + TCPA_DIGEST digest; + TCPA_NONCE antiReplay; + UINT32 CertifyInfoSize; + BYTE *CertifyInfo; + UINT32 outDataSize; + BYTE *outData; + TSS_HPOLICY hPolicy; + TSS_HPOLICY hCertPolicy; + TCS_KEY_HANDLE certifyTCSKeyHandle, keyTCSKeyHandle; + TSS_BOOL useAuthCert; + TSS_BOOL useAuthKey; + TPM_AUTH *pCertAuth = &certAuth; + TPM_AUTH *pKeyAuth = &keyAuth; + TSS_HCONTEXT tspContext; + Trspi_HashCtx hashCtx; + + + if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext))) + return result; + + if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, + &hPolicy, &useAuthKey))) + return result; + + if ((result = obj_rsakey_get_policy(hCertifyingKey, TSS_POLICY_USAGE, + &hCertPolicy, &useAuthCert))) + return result; + + if ((result = obj_rsakey_get_tcs_handle(hCertifyingKey, &certifyTCSKeyHandle))) + return result; + + if ((result = obj_rsakey_get_tcs_handle(hKey, &keyTCSKeyHandle))) + return result; + + if (pValidationData == NULL) { + LogDebug("Internal Verify"); + if ((result = get_local_random(tspContext, FALSE, sizeof(TCPA_NONCE), + (BYTE **)antiReplay.nonce))) + return result; + } else { + LogDebug("External Verify"); + if (pValidationData->ulExternalDataLength < sizeof(antiReplay.nonce)) + return TSPERR(TSS_E_BAD_PARAMETER); + + memcpy(antiReplay.nonce, pValidationData->rgbExternalData, + sizeof(antiReplay.nonce)); + } + + if (useAuthCert && !useAuthKey) + return TSPERR(TSS_E_BAD_PARAMETER); + + /* Setup the auths */ + if (useAuthCert || useAuthKey) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CertifyKey); + result |= Trspi_HashUpdate(&hashCtx, sizeof(antiReplay.nonce), antiReplay.nonce); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + } + + if (useAuthKey) { + if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_CertifyKey, hPolicy, FALSE, + &digest, &keyAuth))) + return result; + } else + pKeyAuth = NULL; + + if (useAuthCert) { + if ((result = secret_PerformAuth_OIAP(hCertifyingKey, TPM_ORD_CertifyKey, + hCertPolicy, FALSE, &digest, + &certAuth))) + return result; + } else + pCertAuth = NULL; + + /* XXX free CertifyInfo */ + if ((result = TCS_API(tspContext)->CertifyKey(tspContext, certifyTCSKeyHandle, + keyTCSKeyHandle, &antiReplay, pCertAuth, + pKeyAuth, &CertifyInfoSize, &CertifyInfo, + &outDataSize, &outData))) + return result; + + /* Validate auth */ + if (useAuthCert || useAuthKey) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CertifyKey); + result |= Trspi_HashUpdate(&hashCtx, CertifyInfoSize, CertifyInfo); + result |= Trspi_Hash_UINT32(&hashCtx, outDataSize); + result |= Trspi_HashUpdate(&hashCtx, outDataSize, outData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if (useAuthKey) + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &keyAuth))) + return result; + + if (useAuthCert) + if ((result = obj_policy_validate_auth_oiap(hCertPolicy, &digest, + &certAuth))) + return result; + } + + if (pValidationData == NULL) { + if ((result = Trspi_Hash(TSS_HASH_SHA1, CertifyInfoSize, CertifyInfo, + digest.digest))) + return result; + + if ((result = __tspi_rsa_verify(hCertifyingKey, TSS_HASH_SHA1, TPM_SHA1_160_HASH_LEN, + digest.digest, outDataSize, outData))) + return TSPERR(TSS_E_VERIFICATION_FAILED); + } else { + pValidationData->ulDataLength = CertifyInfoSize; + pValidationData->rgbData = calloc_tspi(tspContext, CertifyInfoSize); + if (pValidationData->rgbData == NULL) { + LogError("malloc of %u bytes failed.", CertifyInfoSize); + return TSPERR(TSS_E_OUTOFMEMORY); + } + memcpy(pValidationData->rgbData, CertifyInfo, CertifyInfoSize); + pValidationData->ulValidationDataLength = outDataSize; + pValidationData->rgbValidationData = calloc_tspi(tspContext, outDataSize); + if (pValidationData->rgbValidationData == NULL) { + LogError("malloc of %u bytes failed.", outDataSize); + return TSPERR(TSS_E_OUTOFMEMORY); + } + memcpy(pValidationData->rgbValidationData, outData, outDataSize); + } + + return TSS_SUCCESS; +} + diff --git a/src/tspi/tspi_changeauth.c b/src/tspi/tspi_changeauth.c new file mode 100644 index 0000000..1d6d8f1 --- /dev/null +++ b/src/tspi/tspi_changeauth.c @@ -0,0 +1,434 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <errno.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" +#include "authsess.h" + +TSS_RESULT +Tspi_ChangeAuth(TSS_HOBJECT hObjectToChange, /* in */ + TSS_HOBJECT hParentObject, /* in */ + TSS_HPOLICY hNewPolicy) /* in */ +{ + UINT32 keyToChangeHandle; + TSS_RESULT result; + TSS_HCONTEXT tspContext; + + if ((result = obj_policy_get_tsp_context(hNewPolicy, &tspContext))) + return result; + + /* if the object to change is the TPM object, then the parent should + * be NULL. If the object to change is not the TPM, then the parent + * object must be either an rsakey or the TPM */ + if (obj_is_tpm(hObjectToChange)) { + if (hParentObject != NULL_HOBJECT) + return TSPERR(TSS_E_BAD_PARAMETER); + } else if (!obj_is_rsakey(hParentObject) && !obj_is_tpm(hParentObject)) { + return TSPERR(TSS_E_INVALID_HANDLE); + } + + if (obj_is_tpm(hObjectToChange)) { + if ((result = changeauth_owner(tspContext, hObjectToChange, NULL_HTPM, hNewPolicy))) + return result; + } else if (obj_is_rsakey(hObjectToChange)) { + if ((result = obj_rsakey_get_tcs_handle(hObjectToChange, &keyToChangeHandle))) + return result; + + if (keyToChangeHandle == TPM_KEYHND_SRK) { + if ((result = changeauth_srk(tspContext, hObjectToChange, hParentObject, + hNewPolicy))) + return result; + } else { + if ((result = changeauth_key(tspContext, hObjectToChange, hParentObject, + hNewPolicy))) + return result; + } + } else if (obj_is_encdata(hObjectToChange)) { + if ((result = changeauth_encdata(tspContext, hObjectToChange, hParentObject, + hNewPolicy))) + return result; + } else if (obj_is_policy(hObjectToChange) || obj_is_hash(hObjectToChange) || + obj_is_pcrs(hObjectToChange) || obj_is_context(hObjectToChange)) { + return TSPERR(TSS_E_BAD_PARAMETER); + } else { + return TSPERR(TSS_E_INVALID_HANDLE); + } + + if ((result = obj_policy_set_type(hNewPolicy, TSS_POLICY_USAGE))) + return result; + + return Tspi_Policy_AssignToObject(hNewPolicy, hObjectToChange); + +} + +TSS_RESULT +Tspi_ChangeAuthAsym(TSS_HOBJECT hObjectToChange, /* in */ + TSS_HOBJECT hParentObject, /* in */ + TSS_HKEY hIdentKey, /* in */ + TSS_HPOLICY hNewPolicy) /* in */ +{ +#if 0 + TPM_AUTH auth; + UINT64 offset; + BYTE hashBlob[0x1000]; + TCPA_DIGEST digest; + TCPA_RESULT result; + UINT32 keyHandle; + UINT32 idHandle; + TSS_HPOLICY hPolicy; + TSS_HPOLICY hParentPolicy; + UINT32 keyToChangeHandle; + TCPA_NONCE antiReplay; + UINT32 bytesRequested; + UINT64 tempSize; + BYTE tempKey[512]; + TCPA_KEY_PARMS keyParms; + /* XXX Wow... */ + BYTE ephParms[] = { 0, 0, 0x08, 0, 0, 0, 0, 0x02, 0, 0, 0, 0 }; + UINT32 KeySizeOut; + BYTE *KeyDataOut; + UINT32 CertifyInfoSize; + BYTE *CertifyInfo; + UINT32 sigSize; + BYTE *sig; + UINT32 ephHandle; + TPM_CHANGEAUTH_VALIDATE caValidate; + TCPA_SECRET newSecret, oldSecret; + BYTE seed[20]; + BYTE a1[256]; + UINT32 a1Size; + TSS_KEY ephemeralKey; + TCPA_DIGEST newAuthLink; + UINT32 encObjectSize; + BYTE *encObject = NULL; + UINT32 encDataSizeOut; + BYTE *encDataOut; + TCPA_NONCE saltNonce; + TCPA_DIGEST changeProof; + TSS_HPOLICY hOldPolicy; + UINT32 caValidSize; + UINT32 keyObjectSize; + BYTE *keyObject; + TSS_KEY keyContainer; + TCPA_STORED_DATA dataContainer; + BYTE *dataObject; + UINT32 dataObjectSize; + UINT16 entityType; + TSS_BOOL useAuth = TRUE; // XXX + TPM_AUTH *pAuth; + BYTE dataBlob[1024]; + TSS_HCONTEXT tspContext; + Trspi_HashCtx hashCtx; + + if ((result = obj_policy_get_tsp_context(hNewPolicy, &tspContext))) + return result; + + /* grab all of the needed handles */ + if ((result = obj_rsakey_get_tcs_handle(hIdentKey, &idHandle))) + return result; + + /* get the secret for the parent */ + if ((result = obj_rsakey_get_policy(hIdentKey, TSS_POLICY_USAGE, &hPolicy, &useAuth))) + return result; + + /* get the parent secret */ + if ((result = Tspi_GetPolicyObject(hParentObject, TSS_POLICY_USAGE, &hParentPolicy))) + return result; + + if (!obj_is_rsakey(hParentObject) && !obj_is_tpm(hParentObject)) + return TSPERR(TSS_E_INVALID_HANDLE); + + /* get the keyObject */ + if ((result = obj_rsakey_get_tcs_handle(hParentObject, &keyHandle))) + return result; + + if (obj_is_rsakey(hObjectToChange) || + obj_is_encdata(hObjectToChange)) { + + if ((result = obj_rsakey_get_tcs_handle(hObjectToChange, &keyToChangeHandle))) + return result; + + if (keyToChangeHandle == TPM_KEYHND_SRK) { + return TSPERR(TSS_E_BAD_PARAMETER); + } else { + /* generate container for ephemeral key */ + keyParms.algorithmID = 1; /* rsa */ + keyParms.encScheme = 3; + keyParms.sigScheme = 1; + keyParms.parmSize = 12; + keyParms.parms = malloc(12); + if (keyParms.parms == NULL) { + LogError("malloc of %d bytes failed.", 12); + return TSPERR(TSS_E_OUTOFMEMORY); + } + memcpy(keyParms.parms, ephParms, 12); + + tempSize = 0; + Trspi_LoadBlob_KEY_PARMS(&tempSize, tempKey, &keyParms); + + /* generate antireplay nonce */ + bytesRequested = 20; + if ((result = get_local_random(tspContext, FALSE, bytesRequested, + (BYTE **)antiReplay.nonce))) + return result; + + /* caluculate auth data */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthAsymStart); + result |= Trspi_HashUpdate(&hashCtx, TCPA_SHA1_160_HASH_LEN, + antiReplay.nonce); + result |= Trspi_Hash_KEY_PARMS(&hashCtx, &keyParms); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if (useAuth) { + if ((result = secret_PerformAuth_OIAP(hIdentKey, + TPM_ORD_ChangeAuthAsymStart, + hPolicy, FALSE, &digest, + &auth))) + return result; + + pAuth = &auth; + } else { + pAuth = NULL; + } + + if ((result = TCSP_ChangeAuthAsymStart(tspContext, idHandle, antiReplay, + tempSize, tempKey, pAuth, + &KeySizeOut, &KeyDataOut, + &CertifyInfoSize, &CertifyInfo, + &sigSize, &sig, &ephHandle))) + return result; + + /* Validate the Auth's */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthAsymStart); + result |= Trspi_HashUpdate(&hashCtx, CertifyInfoSize, CertifyInfo); + result |= Trspi_Hash_UINT32(&hashCtx, sigSize); + result |= Trspi_HashUpdate(&hashCtx, sigSize, sig); + result |= Trspi_Hash_UINT32(&hashCtx, ephHandle); + result |= Trspi_HashUpdate(&hashCtx, KeySizeOut, KeyDataOut); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if (useAuth) { + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, + &auth))) + return result; + } + + /* generate random data for asymfinish */ + if ((result = get_local_random(tspContext, FALSE, bytesRequested, + (BYTE **)&caValidate.n1.nonce))) + return result; + + if ((result = get_local_random(tspContext, FALSE, bytesRequested, + (BYTE **)&antiReplay.nonce))) + return result; + + if ((result = get_local_random(tspContext, FALSE, bytesRequested, + (BYTE **)&seed))) + return result; + + if ((result = Tspi_GetPolicyObject(hObjectToChange, TSS_POLICY_USAGE, + &hOldPolicy))) + return result; + + if ((result = obj_policy_get_secret(hNewPolicy, TR_SECRET_CTX_NEW, + &newSecret))) + return result; + if ((result = obj_policy_get_secret(hOldPolicy, TR_SECRET_CTX_NOT_NEW, + &oldSecret))) + return result; + + /* Encrypt the ChangeAuthValidate structure with the + * ephemeral key */ + + memcpy(caValidate.newAuthSecret.authdata, newSecret.authdata, 20); + + offset = 0; + Trspi_LoadBlob_CHANGEAUTH_VALIDATE(&offset, hashBlob, &caValidate); + caValidSize = offset; + + offset = 0; + if ((result = UnloadBlob_TSS_KEY(&offset, KeyDataOut, &ephemeralKey))) + return result; + + Trspi_RSA_Encrypt(hashBlob, caValidSize, a1, &a1Size, + ephemeralKey.pubKey.key, + ephemeralKey.pubKey.keyLength); + + free_key_refs(&ephemeralKey); + + Trspi_HMAC(TSS_HASH_SHA1, 20, oldSecret.authdata, + 20, newSecret.authdata, + newAuthLink.digest); + + if (obj_is_rsakey(hObjectToChange)) { + if ((result = obj_rsakey_get_blob(hObjectToChange, + &keyObjectSize, &keyObject))) + return result; + + memset(&keyContainer, 0, sizeof(TSS_KEY)); + + offset = 0; + if ((result = UnloadBlob_TSS_KEY(&offset, + keyObject, + &keyContainer))) + return result; + + encObjectSize = keyContainer.encSize; + encObject = malloc(encObjectSize); + if (encObject == NULL) { + LogError("malloc of %d bytes failed.", + encObjectSize); + free_key_refs(&keyContainer); + return TSPERR(TSS_E_OUTOFMEMORY); + } + memcpy(encObject, keyContainer.encData, + encObjectSize); + entityType = TCPA_ET_KEY; + } else { + if ((result = obj_encdata_get_data(hObjectToChange, + &dataObjectSize, &dataObject))) + return result; + + offset = 0; + if ((result = Trspi_UnloadBlob_STORED_DATA(&offset, + dataObject, + &dataContainer))) + return result; + + encObjectSize = dataContainer.encDataSize; + encObject = malloc(encObjectSize); + if (encObject == NULL) { + LogError("malloc of %d bytes failed.", encObjectSize); + free(dataContainer.sealInfo); + free(dataContainer.encData); + return TSPERR(TSS_E_OUTOFMEMORY); + } + memcpy(encObject, dataContainer.encData, + encObjectSize); + entityType = TCPA_ET_DATA; + } + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthAsymFinish); + result |= Trspi_Hash_UINT16(&hashCtx, entityType); + result |= Trspi_HashUpdate(&hashCtx, TCPA_SHA1_160_HASH_LEN, + newAuthLink.digest); + result |= Trspi_Hash_UINT32(&hashCtx, a1Size); + result |= Trspi_HashUpdate(&hashCtx, a1Size, a1); + result |= Trspi_Hash_UINT32(&hashCtx, encObjectSize); + result |= Trspi_HashUpdate(&hashCtx, encObjectSize, encObject); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if (useAuth) { + if ((result = secret_PerformAuth_OIAP(hParentObject, + TPM_ORD_ChangeAuthAsymFinish, + hParentPolicy, FALSE, + &digest, &auth))) { + free(encObject); + free_key_refs(&keyContainer); + return result; + } + pAuth = &auth; + } else { + pAuth = NULL; + } + + if ((result = TCSP_ChangeAuthAsymFinish(tspContext, keyHandle, ephHandle, + entityType, newAuthLink, a1Size, a1, + encObjectSize, encObject, pAuth, + &encDataSizeOut, &encDataOut, + &saltNonce, &changeProof))) { + free_key_refs(&keyContainer); + free(encObject); + return result; + } + + /* --- Validate the Auth's */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ChangeAuthAsymFinish); + result |= Trspi_Hash_UINT32(&hashCtx, encDataSizeOut); + result |= Trspi_HashUpdate(&hashCtx, encDataSizeOut, encDataOut); + result |= Trspi_HashUpdate(&hashCtx, TCPA_SHA1_160_HASH_LEN, + saltNonce.nonce); + result |= Trspi_HashUpdate(&hashCtx, TCPA_SHA1_160_HASH_LEN, + changeProof.digest); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if (useAuth) { + if ((result = obj_policy_validate_auth_oiap(hParentPolicy, + &digest, + &auth))) { + free_key_refs(&keyContainer); + free(encObject); + return result; + } + } + + if (entityType == TCPA_ET_KEY || + entityType == TCPA_ET_KEYHANDLE) { + memcpy(keyContainer.encData, encDataOut, encDataSizeOut); + keyContainer.encSize = encDataSizeOut; + + offset = 0; + LoadBlob_TSS_KEY(&offset, keyObject, &keyContainer); + free_key_refs(&keyContainer); + if ((result = obj_rsakey_set_tcpakey(hObjectToChange, offset, + keyObject))) { + free(encObject); + return result; + } + } + + if (entityType == TCPA_ET_DATA) { + memcpy(dataContainer.encData, encDataOut, + encDataSizeOut); + dataContainer.encDataSize = encDataSizeOut; + + offset = 0; + Trspi_LoadBlob_STORED_DATA(&offset, dataBlob, + &dataContainer); + free(dataContainer.sealInfo); + free(dataContainer.encData); + obj_encdata_set_data(hObjectToChange, + offset, dataBlob); + } + } + } else + return TSPERR(TSS_E_BAD_PARAMETER); + + free(encObject); + + return Tspi_Policy_AssignToObject(hNewPolicy, hObjectToChange); +#else + return TSPERR(TSS_E_NOTIMPL); +#endif +} + diff --git a/src/tspi/tspi_cmk.c b/src/tspi/tspi_cmk.c new file mode 100644 index 0000000..6ced203 --- /dev/null +++ b/src/tspi/tspi_cmk.c @@ -0,0 +1,475 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "obj.h" +#include "tsplog.h" + + +TSS_RESULT +Tspi_TPM_CMKSetRestrictions(TSS_HTPM hTpm, /* in */ + TSS_CMK_DELEGATE CmkDelegate) /* in */ +{ + TSS_HCONTEXT hContext; + TSS_HPOLICY hPolicy; + Trspi_HashCtx hashCtx; + TPM_DIGEST digest; + TPM_AUTH ownerAuth; + TSS_RESULT result; + + if ((result = obj_tpm_get_tsp_context(hTpm, &hContext))) + return result; + + if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_SetRestrictions); + result |= Trspi_Hash_UINT32(&hashCtx, CmkDelegate); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_CMK_SetRestrictions, + hPolicy, FALSE, &digest, &ownerAuth))) + return result; + + if ((result = RPC_CMK_SetRestrictions(hContext, CmkDelegate, &ownerAuth))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_SetRestrictions); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth))) + return result; + + return result; +} + +TSS_RESULT +Tspi_TPM_CMKApproveMA(TSS_HTPM hTpm, /* in */ + TSS_HMIGDATA hMaAuthData) /* in */ +{ + TSS_HCONTEXT hContext; + TSS_HPOLICY hPolicy; + UINT32 blobSize; + BYTE *blob; + TPM_DIGEST msaDigest; + TPM_HMAC msaHmac; + Trspi_HashCtx hashCtx; + TPM_DIGEST digest; + TPM_AUTH ownerAuth; + TSS_RESULT result; + + if ((result = obj_tpm_get_tsp_context(hTpm, &hContext))) + return result; + + if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy))) + return result; + + if ((result = obj_migdata_get_msa_digest(hMaAuthData, &blobSize, &blob))) + return result; + memcpy(msaDigest.digest, blob, sizeof(msaDigest.digest)); + free_tspi(hContext, blob); + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_ApproveMA); + result |= Trspi_Hash_DIGEST(&hashCtx, msaDigest.digest); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_CMK_ApproveMA, + hPolicy, FALSE, &digest, &ownerAuth))) + return result; + + if ((result = RPC_CMK_ApproveMA(hContext, msaDigest, &ownerAuth, &msaHmac))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_ApproveMA); + result |= Trspi_Hash_HMAC(&hashCtx, msaHmac.digest); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth))) + return result; + + if ((result = obj_migdata_set_msa_hmac(hMaAuthData, sizeof(msaHmac.digest), msaHmac.digest))) + return result; + + return result; +} + +TSS_RESULT +Tspi_TPM_CMKCreateTicket(TSS_HTPM hTpm, /* in */ + TSS_HKEY hVerifyKey, /* in */ + TSS_HMIGDATA hSigData) /* in */ +{ + TSS_HCONTEXT hContext; + TSS_HPOLICY hPolicy; + UINT32 pubKeySize; + BYTE *pubKey = NULL; + UINT32 blobSize; + BYTE *blob; + TPM_DIGEST sigData; + UINT32 sigSize; + BYTE *sig = NULL; + TPM_HMAC sigTicket; + Trspi_HashCtx hashCtx; + TPM_DIGEST digest; + TPM_AUTH ownerAuth; + TSS_RESULT result; + + if ((result = obj_tpm_get_tsp_context(hTpm, &hContext))) + return result; + + if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy))) + return result; + + if ((result = obj_rsakey_get_pub_blob(hVerifyKey, &pubKeySize, &pubKey))) + return result; + + if ((result = obj_migdata_get_sig_data(hSigData, &blobSize, &blob))) + goto done; + memcpy(sigData.digest, blob, sizeof(sigData.digest)); + free_tspi(hContext, blob); + + if ((result = obj_migdata_get_sig_value(hSigData, &sigSize, &sig))) + goto done; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_CreateTicket); + result |= Trspi_HashUpdate(&hashCtx, pubKeySize, pubKey); + result |= Trspi_Hash_DIGEST(&hashCtx, sigData.digest); + result |= Trspi_Hash_UINT32(&hashCtx, sigSize); + result |= Trspi_HashUpdate(&hashCtx, sigSize, sig); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_CMK_CreateTicket, + hPolicy, FALSE, &digest, &ownerAuth))) + goto done; + + if ((result = RPC_CMK_CreateTicket(hContext, pubKeySize, pubKey, sigData, sigSize, sig, + &ownerAuth, &sigTicket))) + goto done; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_CreateTicket); + result |= Trspi_Hash_HMAC(&hashCtx, sigTicket.digest); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth))) + goto done; + + if ((result = obj_migdata_set_sig_ticket(hSigData, sizeof(sigTicket.digest), sigTicket.digest))) + goto done; + +done: + free_tspi(hContext, pubKey); + free_tspi(hContext, sig); + + return result; +} + +TSS_RESULT +Tspi_Key_CMKCreateBlob(TSS_HKEY hKeyToMigrate, /* in */ + TSS_HKEY hParentKey, /* in */ + TSS_HMIGDATA hMigrationData, /* in */ + UINT32* pulRandomLength, /* out */ + BYTE** prgbRandom) /* out */ +{ + TSS_HCONTEXT hContext; + TSS_HPOLICY hPolicy; + TSS_BOOL usageAuth; + TCS_KEY_HANDLE tcsKeyHandle; + TSS_MIGRATE_SCHEME migScheme; + UINT32 migTicketSize; + BYTE *migTicket = NULL; + TPM_MIGRATIONKEYAUTH tpmMigKeyAuth; + UINT32 msaListSize, restrictTicketSize, sigTicketSize, blobSize; + BYTE *msaList = NULL, *restrictTicket = NULL, *blob = NULL; + BYTE *sigTicket = NULL; + UINT32 pubBlobSize; + BYTE *pubBlob = NULL; + TPM_DIGEST srcPubKeyDigest; + TSS_KEY tssKey; + UINT32 randomDataSize, outDataSize, newBlobSize; + BYTE *randomData = NULL, *outData = NULL, *newBlob = NULL; + Trspi_HashCtx hashCtx; + TPM_DIGEST digest; + TPM_AUTH parentAuth, *pAuth; + UINT64 offset; + TSS_RESULT result; + + memset(&tssKey, 0, sizeof(tssKey)); + + if (!pulRandomLength || !prgbRandom) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (!obj_rsakey_is_cmk(hKeyToMigrate)) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_rsakey_get_tsp_context(hKeyToMigrate, &hContext))) + return result; + + if ((result = obj_rsakey_get_policy(hParentKey, TSS_POLICY_USAGE, &hPolicy, &usageAuth))) + return result; + + if ((result = obj_rsakey_get_tcs_handle(hParentKey, &tcsKeyHandle))) + return result; + + if ((result = obj_migdata_get_ticket_blob(hMigrationData, &migTicketSize, &migTicket))) + return result; + + /* Just to get the migration scheme... */ + offset = 0; + if ((result = Trspi_UnloadBlob_MIGRATIONKEYAUTH(&offset, migTicket, &tpmMigKeyAuth))) + goto done; + /* ... so free everything now */ + free(tpmMigKeyAuth.migrationKey.algorithmParms.parms); + free(tpmMigKeyAuth.migrationKey.pubKey.key); + migScheme = tpmMigKeyAuth.migrationScheme; + + if ((result = obj_rsakey_get_pub_blob(hKeyToMigrate, &pubBlobSize, &pubBlob))) + goto done; + if ((result = obj_migdata_calc_pubkey_digest(pubBlobSize, pubBlob, &srcPubKeyDigest))) + goto done; + + if ((result = obj_migdata_get_msa_list_blob(hMigrationData, &msaListSize, &msaList))) + goto done; + + if (tpmMigKeyAuth.migrationScheme == TPM_MS_RESTRICT_APPROVE_DOUBLE) { + if ((result = obj_migdata_get_cmk_auth_blob(hMigrationData, &restrictTicketSize, + &restrictTicket))) + goto done; + if ((result = obj_migdata_get_sig_ticket(hMigrationData, &sigTicketSize, + &sigTicket))) + goto done; + } else { + restrictTicketSize = 0; + sigTicketSize = 0; + } + + if ((result = obj_rsakey_get_blob(hKeyToMigrate, &blobSize, &blob))) + goto done; + + offset = 0; + if ((result = UnloadBlob_TSS_KEY(&offset, blob, &tssKey))) + goto done; + + if (usageAuth) { + pAuth = &parentAuth; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_CreateBlob); + result |= Trspi_Hash_UINT16(&hashCtx, migScheme); + result |= Trspi_HashUpdate(&hashCtx, migTicketSize, migTicket); + result |= Trspi_Hash_DIGEST(&hashCtx, srcPubKeyDigest.digest); + result |= Trspi_Hash_UINT32(&hashCtx, msaListSize); + result |= Trspi_HashUpdate(&hashCtx, msaListSize, msaList); + result |= Trspi_Hash_UINT32(&hashCtx, restrictTicketSize); + result |= Trspi_HashUpdate(&hashCtx, restrictTicketSize, restrictTicket); + result |= Trspi_Hash_UINT32(&hashCtx, sigTicketSize); + result |= Trspi_HashUpdate(&hashCtx, sigTicketSize, sigTicket); + result |= Trspi_Hash_UINT32(&hashCtx, tssKey.encSize); + result |= Trspi_HashUpdate(&hashCtx, tssKey.encSize, tssKey.encData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if ((result = secret_PerformAuth_OIAP(hParentKey, TPM_ORD_CMK_CreateBlob, + hPolicy, FALSE, &digest, pAuth))) + goto done; + } else + pAuth = NULL; + + if ((result = RPC_CMK_CreateBlob(hContext, tcsKeyHandle, migScheme, + migTicketSize, migTicket, srcPubKeyDigest, msaListSize, msaList, + restrictTicketSize, restrictTicket, sigTicketSize, sigTicket, + tssKey.encSize, tssKey.encData, pAuth, &randomDataSize, &randomData, + &outDataSize, &outData))) + goto done; + + if (pAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_CreateBlob); + result |= Trspi_Hash_UINT32(&hashCtx, randomDataSize); + result |= Trspi_HashUpdate(&hashCtx, randomDataSize, randomData); + result |= Trspi_Hash_UINT32(&hashCtx, outDataSize); + result |= Trspi_HashUpdate(&hashCtx, outDataSize, outData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + } + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth))) + goto done; + + /* Create the migdata key blob */ + free(tssKey.encData); + tssKey.encSize = outDataSize; + tssKey.encData = outData; + /* Set outData to null since it will now be freed during key ref freeing */ + outData = NULL; + + offset = 0; + LoadBlob_TSS_KEY(&offset, NULL, &tssKey); + + newBlobSize = offset; + if ((newBlob = malloc(newBlobSize)) == NULL) { + LogError("malloc of %u bytes failed.", newBlobSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + offset = 0; + LoadBlob_TSS_KEY(&offset, newBlob, &tssKey); + + if ((result = obj_migdata_set_blob(hMigrationData, newBlobSize, newBlob))) + goto done; + + if ((*prgbRandom = calloc_tspi(hContext, randomDataSize)) == NULL) { + LogError("malloc of %u bytes failed.", randomDataSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(*prgbRandom, randomData, randomDataSize); + *pulRandomLength = randomDataSize; + +done: + free_tspi(hContext, migTicket); + free_tspi(hContext, pubBlob); + free_tspi(hContext, msaList); + free_tspi(hContext, restrictTicket); + free_tspi(hContext, sigTicket); + free_tspi(hContext, blob); + free(randomData); + free(outData); + free(newBlob); + free_key_refs(&tssKey); + + return result; +} + +TSS_RESULT +Tspi_Key_CMKConvertMigration(TSS_HKEY hKeyToMigrate, /* in */ + TSS_HKEY hParentKey, /* in */ + TSS_HMIGDATA hMigrationData, /* in */ + UINT32 ulRandomLength, /* in */ + BYTE* rgbRandom) /* in */ +{ + TSS_HCONTEXT hContext; + TSS_HPOLICY hPolicy; + TSS_BOOL usageAuth; + TCS_KEY_HANDLE tcsKeyHandle; + TPM_CMK_AUTH restrictTicket; + UINT32 blobSize; + BYTE *blob; + TPM_HMAC sigTicket; + UINT32 migDataSize, msaListSize; + BYTE *migData = NULL, *msaList = NULL; + UINT32 outDataSize; + BYTE *outData = NULL; + Trspi_HashCtx hashCtx; + TPM_DIGEST digest; + TPM_AUTH parentAuth, *pAuth; + TSS_RESULT result; + + if ((result = obj_rsakey_get_tsp_context(hKeyToMigrate, &hContext))) + return result; + + if ((result = obj_rsakey_get_policy(hParentKey, TSS_POLICY_USAGE, &hPolicy, &usageAuth))) + return result; + + if ((result = obj_rsakey_get_tcs_handle(hParentKey, &tcsKeyHandle))) + return result; + + if ((result = obj_migdata_get_cmk_auth(hMigrationData, &restrictTicket))) + return result; + + if ((result = obj_migdata_get_sig_ticket(hMigrationData, &blobSize, &blob))) + return result; + memcpy(sigTicket.digest, blob, sizeof(sigTicket.digest)); + free_tspi(hContext, blob); + + if ((result = obj_migdata_get_blob(hMigrationData, &migDataSize, &migData))) + goto done; + + if ((result = obj_migdata_get_msa_list_blob(hMigrationData, &msaListSize, &msaList))) + goto done; + + if (usageAuth) { + pAuth = &parentAuth; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_ConvertMigration); + result |= Trspi_HashUpdate(&hashCtx, sizeof(restrictTicket), + (BYTE *)&restrictTicket); + result |= Trspi_Hash_HMAC(&hashCtx, sigTicket.digest); + result |= Trspi_HashUpdate(&hashCtx, migDataSize, migData); + result |= Trspi_Hash_UINT32(&hashCtx, msaListSize); + result |= Trspi_HashUpdate(&hashCtx, msaListSize, msaList); + result |= Trspi_Hash_UINT32(&hashCtx, ulRandomLength); + result |= Trspi_HashUpdate(&hashCtx, ulRandomLength, rgbRandom); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if ((result = secret_PerformAuth_OIAP(hParentKey, TPM_ORD_CMK_ConvertMigration, + hPolicy, FALSE, &digest, pAuth))) + goto done; + } else + pAuth = NULL; + + if ((result = RPC_CMK_ConvertMigration(hContext, tcsKeyHandle, restrictTicket, sigTicket, + migDataSize, migData, msaListSize, msaList, ulRandomLength, rgbRandom, + pAuth, &outDataSize, &outData))) + goto done; + + if (pAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CMK_ConvertMigration); + result |= Trspi_Hash_UINT32(&hashCtx, outDataSize); + result |= Trspi_HashUpdate(&hashCtx, outDataSize, outData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + } + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth))) + goto done; + + /* Set the key object to the now migrated key */ + if ((result = obj_rsakey_set_tcpakey(hKeyToMigrate, migDataSize, migData))) + goto done; + if ((result = obj_rsakey_set_privkey(hKeyToMigrate, TRUE, outDataSize, outData))) + goto done; + result = obj_rsakey_set_tcs_handle(hKeyToMigrate, 0); + +done: + free_tspi(hContext, migData); + free_tspi(hContext, msaList); + free(outData); + + return result; +} + diff --git a/src/tspi/tspi_context.c b/src/tspi/tspi_context.c new file mode 100644 index 0000000..c935a28 --- /dev/null +++ b/src/tspi/tspi_context.c @@ -0,0 +1,381 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "tcs_tsp.h" +#include "tspps.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "tcsd.h" +#include "obj.h" + + +TSS_RESULT +Tspi_Context_Create(TSS_HCONTEXT * phContext) /* out */ +{ + if (phContext == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + return obj_context_add(phContext); +} + +TSS_RESULT +Tspi_Context_Close(TSS_HCONTEXT tspContext) /* in */ +{ + if (!obj_is_context(tspContext)) + return TSPERR(TSS_E_INVALID_HANDLE); + + obj_context_close(tspContext); + + /* Have the TCS do its thing */ + RPC_CloseContext(tspContext); + + /* Note: Memory that was returned to the app that was alloc'd by this + * context isn't free'd here. Any memory that the app doesn't explicitly + * free is left for it to free itself. */ + + /* Destroy all objects */ + obj_close_context(tspContext); + + Tspi_Context_FreeMemory(tspContext, NULL); + + /* close the ps file */ + PS_close(); + + /* We're not a connected context, so just exit */ + return TSS_SUCCESS; +} + +TSS_RESULT +Tspi_Context_Connect(TSS_HCONTEXT tspContext, /* in */ + TSS_UNICODE *wszDestination) /* in */ +{ + TSS_RESULT result; + BYTE *machine_name = NULL; + TSS_HOBJECT hTpm; + UINT32 string_len = 0; + + + if (wszDestination == NULL) { + if ((result = obj_context_get_machine_name(tspContext, + &string_len, + &machine_name))) + return result; + + if ((result = RPC_OpenContext(tspContext, machine_name, + CONNECTION_TYPE_TCP_PERSISTANT))) + return result; + } else { + if ((machine_name = + Trspi_UNICODE_To_Native((BYTE *)wszDestination, NULL)) == NULL) { + LogError("Error converting hostname to UTF-8"); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + if ((result = RPC_OpenContext(tspContext, machine_name, + CONNECTION_TYPE_TCP_PERSISTANT))) + return result; + + if ((result = obj_context_set_machine_name(tspContext, machine_name, + strlen((char *)machine_name)+1))) + return result; + } + + if ((obj_tpm_add(tspContext, &hTpm))) + return TSPERR(TSS_E_INTERNAL_ERROR); + + return TSS_SUCCESS; +} + +TSS_RESULT +Tspi_Context_FreeMemory(TSS_HCONTEXT tspContext, /* in */ + BYTE * rgbMemory) /* in */ +{ + if (!obj_is_context(tspContext)) + return TSPERR(TSS_E_INVALID_HANDLE); + + return free_tspi(tspContext, rgbMemory); +} + +TSS_RESULT +Tspi_Context_GetDefaultPolicy(TSS_HCONTEXT tspContext, /* in */ + TSS_HPOLICY * phPolicy) /* out */ +{ + if (phPolicy == NULL ) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (!obj_is_context(tspContext)) + return TSPERR(TSS_E_INVALID_HANDLE); + + return obj_context_get_policy(tspContext, TSS_POLICY_USAGE, phPolicy); +} + +TSS_RESULT +Tspi_Context_CreateObject(TSS_HCONTEXT tspContext, /* in */ + TSS_FLAG objectType, /* in */ + TSS_FLAG initFlags, /* in */ + TSS_HOBJECT * phObject) /* out */ +{ + TSS_RESULT result; + + if (phObject == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (!obj_is_context(tspContext)) + return TSPERR(TSS_E_INVALID_HANDLE); + + switch (objectType) { + case TSS_OBJECT_TYPE_POLICY: + switch (initFlags) { +#ifdef TSS_BUILD_TSS12 + case TSS_POLICY_OPERATOR: + /* fall through */ +#endif + case TSS_POLICY_MIGRATION: + /* fall through */ + case TSS_POLICY_USAGE: + break; + default: + return TSPERR(TSS_E_INVALID_OBJECT_INITFLAG); + } + + result = obj_policy_add(tspContext, initFlags, phObject); + break; +#ifdef TSS_BUILD_RSAKEY_LIST + case TSS_OBJECT_TYPE_RSAKEY: + /* If other flags are set that disagree with the SRK, this will + * help catch that conflict in the later steps */ + if (initFlags & TSS_KEY_TSP_SRK) { + initFlags |= (TSS_KEY_TYPE_STORAGE | TSS_KEY_NOT_MIGRATABLE | + TSS_KEY_NON_VOLATILE | TSS_KEY_SIZE_2048); + } + + /* Set default key flags */ + + /* Default key size = 2k */ + if ((initFlags & TSS_KEY_SIZE_MASK) == 0) + initFlags |= TSS_KEY_SIZE_2048; + + /* Default key type = storage */ + if ((initFlags & TSS_KEY_TYPE_MASK) == 0) + initFlags |= TSS_KEY_TYPE_STORAGE; + + /* Check the key flags */ + switch (initFlags & TSS_KEY_SIZE_MASK) { + case TSS_KEY_SIZE_512: + /* fall through */ + case TSS_KEY_SIZE_1024: + /* fall through */ + case TSS_KEY_SIZE_2048: + /* fall through */ + case TSS_KEY_SIZE_4096: + /* fall through */ + case TSS_KEY_SIZE_8192: + /* fall through */ + case TSS_KEY_SIZE_16384: + break; + default: + return TSPERR(TSS_E_INVALID_OBJECT_INITFLAG); + } + + switch (initFlags & TSS_KEY_TYPE_MASK) { + case TSS_KEY_TYPE_STORAGE: + /* fall through */ + case TSS_KEY_TYPE_SIGNING: + /* fall through */ + case TSS_KEY_TYPE_BIND: + /* fall through */ + case TSS_KEY_TYPE_AUTHCHANGE: + /* fall through */ + case TSS_KEY_TYPE_LEGACY: + /* fall through */ + case TSS_KEY_TYPE_IDENTITY: + break; + default: + return TSPERR(TSS_E_INVALID_OBJECT_INITFLAG); + } + + result = obj_rsakey_add(tspContext, initFlags, phObject); + break; +#endif +#ifdef TSS_BUILD_ENCDATA_LIST + case TSS_OBJECT_TYPE_ENCDATA: + switch (initFlags & TSS_ENCDATA_TYPE_MASK) { + case TSS_ENCDATA_LEGACY: + /* fall through */ + case TSS_ENCDATA_SEAL: + /* fall through */ + case TSS_ENCDATA_BIND: + break; + default: + return TSPERR(TSS_E_INVALID_OBJECT_INITFLAG); + } + + result = obj_encdata_add(tspContext, (initFlags & TSS_ENCDATA_TYPE_MASK), phObject); + break; +#endif +#ifdef TSS_BUILD_PCRS_LIST + case TSS_OBJECT_TYPE_PCRS: + switch (initFlags) { + case TSS_PCRS_STRUCT_DEFAULT: + /* fall through */ + case TSS_PCRS_STRUCT_INFO: + /* fall through */ + case TSS_PCRS_STRUCT_INFO_LONG: + /* fall through */ + case TSS_PCRS_STRUCT_INFO_SHORT: + /* fall through */ + break; + default: + return TSPERR(TSS_E_INVALID_OBJECT_INITFLAG); + } + + result = obj_pcrs_add(tspContext, initFlags, phObject); + break; +#endif +#ifdef TSS_BUILD_HASH_LIST + case TSS_OBJECT_TYPE_HASH: + switch (initFlags) { + case TSS_HASH_DEFAULT: + /* fall through */ + case TSS_HASH_SHA1: + /* fall through */ + case TSS_HASH_OTHER: + break; + default: + return TSPERR(TSS_E_INVALID_OBJECT_INITFLAG); + } + + result = obj_hash_add(tspContext, initFlags, phObject); + break; +#endif +#ifdef TSS_BUILD_DAA + //case TSS_OBJECT_TYPE_DAA_CREDENTIAL: + case TSS_OBJECT_TYPE_DAA_CERTIFICATE: + if (initFlags & ~(0UL)) + return TSPERR(TSS_E_INVALID_OBJECT_INITFLAG); + + result = obj_daacred_add(tspContext, phObject); + break; + case TSS_OBJECT_TYPE_DAA_ISSUER_KEY: + if (initFlags & ~(0UL)) + return TSPERR(TSS_E_INVALID_OBJECT_INITFLAG); + + result = obj_daaissuerkey_add(tspContext, phObject); + break; + case TSS_OBJECT_TYPE_DAA_ARA_KEY: + if (initFlags & ~(0UL)) + return TSPERR(TSS_E_INVALID_OBJECT_INITFLAG); + + result = obj_daaarakey_add(tspContext, phObject); + break; +#endif +#ifdef TSS_BUILD_NV + case TSS_OBJECT_TYPE_NV: + /* There are no valid flags for a NV object */ + if (initFlags & ~(0UL)) + return TSPERR(TSS_E_INVALID_OBJECT_INITFLAG); + + result = obj_nvstore_add(tspContext, phObject); + break; +#endif +#ifdef TSS_BUILD_DELEGATION + case TSS_OBJECT_TYPE_DELFAMILY: + /* There are no valid flags for a DELFAMILY object */ + if (initFlags & ~(0UL)) + return TSPERR(TSS_E_INVALID_OBJECT_INITFLAG); + + result = obj_delfamily_add(tspContext, phObject); + break; +#endif +#ifdef TSS_BUILD_CMK + case TSS_OBJECT_TYPE_MIGDATA: + /* There are no valid flags for a MIGDATA object */ + if (initFlags & ~(0UL)) + return TSPERR(TSS_E_INVALID_OBJECT_INITFLAG); + + result = obj_migdata_add(tspContext, phObject); + break; +#endif + default: + LogDebug("Invalid Object type"); + return TSPERR(TSS_E_INVALID_OBJECT_TYPE); + break; + } + + return result; +} + +TSS_RESULT +Tspi_Context_CloseObject(TSS_HCONTEXT tspContext, /* in */ + TSS_HOBJECT hObject) /* in */ +{ + TSS_RESULT result; + + if (!obj_is_context(tspContext)) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (obj_is_pcrs(hObject)) { +#ifdef TSS_BUILD_PCRS_LIST + result = obj_pcrs_remove(hObject, tspContext); +#endif + } else if (obj_is_encdata(hObject)) { +#ifdef TSS_BUILD_ENCDATA_LIST + result = obj_encdata_remove(hObject, tspContext); +#endif + } else if (obj_is_hash(hObject)) { +#ifdef TSS_BUILD_HASH_LIST + result = obj_hash_remove(hObject, tspContext); +#endif + } else if (obj_is_rsakey(hObject)) { +#ifdef TSS_BUILD_RSAKEY_LIST + result = obj_rsakey_remove(hObject, tspContext); +#endif + } else if (obj_is_policy(hObject)) { + result = obj_policy_remove(hObject, tspContext); + } else if (obj_is_delfamily(hObject)) { +#ifdef TSS_BUILD_DELEGATION + result = obj_delfamily_remove(hObject, tspContext); +#endif + } else if (obj_is_migdata(hObject)) { +#ifdef TSS_BUILD_CMK + result = obj_migdata_remove(hObject, tspContext); +#endif + } else { + result = TSPERR(TSS_E_INVALID_HANDLE); + } + + return result; +} + +TSS_RESULT +Tspi_Context_GetTpmObject(TSS_HCONTEXT tspContext, /* in */ + TSS_HTPM * phTPM) /* out */ +{ + if (phTPM == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (!obj_is_context(tspContext)) + return TSPERR(TSS_E_INVALID_HANDLE); + + return obj_tpm_get(tspContext, phTPM); +} + diff --git a/src/tspi/tspi_counter.c b/src/tspi/tspi_counter.c new file mode 100644 index 0000000..d494cc1 --- /dev/null +++ b/src/tspi/tspi_counter.c @@ -0,0 +1,48 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_TPM_ReadCounter(TSS_HTPM hTPM, /* in */ + UINT32* counterValue) /* out */ +{ + TSS_HCONTEXT tspContext; + TCPA_RESULT result; + TSS_COUNTER_ID counterID; + TPM_COUNTER_VALUE counter_value; + + if (counterValue == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if ((result = obj_tpm_get_current_counter(hTPM, &counterID))) + return result; + + if ((result = TCS_API(tspContext)->ReadCounter(tspContext, counterID, &counter_value))) + return result; + + *counterValue = counter_value.counter; + + return TSS_SUCCESS; +} diff --git a/src/tspi/tspi_daa.c b/src/tspi/tspi_daa.c new file mode 100644 index 0000000..f68849c --- /dev/null +++ b/src/tspi/tspi_daa.c @@ -0,0 +1,698 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <malloc.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +//#include "trousers_types.h" +#include "spi_utils.h" +//#include "capabilities.h" +#include "tsplog.h" +//#include "tcs_tsp.h" +//#include "tspps.h" +//#include "hosttable.h" +//#include "tcsd_wrap.h" +//#include "tcsd.h" +#include "obj.h" +#include "daa/issuer.h" +#include "daa/platform.h" +#include "daa/verifier.h" +#include "daa/anonymity_revocation.h" + +#include "daa/key_correct.h" +#include "daa/issuer.h" + +// static TSS_HCONTEXT _hContext; + +static void *tss_alloc( size_t size, TSS_HOBJECT hContext) { + void *ret = calloc_tspi( hContext, size); + + LogDebug("[intern_alloc (%d)] -> %d", (int)size, (int)ret); + return ret; +} + +/* +static void *normal_malloc( size_t size, TSS_HOBJECT object) { + void *ret = malloc( size); + return ret; +} +*/ + +/** +This is the first out of 3 functions to execute in order to receive a DAA Credential. +It verifies the keys of the DAA Issuer and computes the TPM DAA public key. + +Parameters + - hDAA: Handle of the DAA object + - hTPM: Handle of the TPM object + - daaCounter: DAA counter + - issuerPk: Handle of the DAA Issuer public key + - issuerAuthPKsLength: Length of the array of issuerAuthPKs + - issuerAuthPKs:Handle of an array of RSA public keys (key chain) of the DAA Issuer used + to authenticate the DAA Issuer public key. The size of the modulus + must be TPM_DAA_SIZE_issuerModulus (256) + - issuerAuthPKSignaturesLength:Length of the array of issuerAuthPKSignatures. It is equal + to issuerAuthPKsLength . The length of an element of the array is + TPM_DAA_SIZE_issuerModulus (256) + - issuerAuthPKSignatures: An array of byte arrays representing signatures on the modulus + of the above key chain (issuerAuthPKs) in more details, the array has the + following content (S(K[1],K[0]),S(K[2],N[1]),..S(K[ k ],K[n-1]), + S(TPM_DAA_ISSUER,K[ k ])), where S(msg,privateKey) denotes + the signature function with msg being signed by the privateKey. + - capitalUprimeLength: Length of capitalUprime which is ln/8. ln is defined as the size of the RSA modulus (2048). + - capitalUprime: U? + - identityProof: This structure contains the endorsement, platform and conformance credential. + - joinSession: This structure contains DAA Join session information. +*/ +#if 0 +TSPICALL +Tspi_TPM_DAA_JoinInit(TSS_HDAA hDAA, // in + TSS_HTPM hTPM, // in + UINT32 daaCounter, // in + TSS_HDAA_DATA issuerPk, // in + UINT32 issuerAuthPKsLength, // in + TSS_HKEY* issuerAuthPKs, // in + UINT32 issuerAuthPKSignaturesLength, // in + BYTE** issuerAuthPKSignatures, // in + UINT32* capitalUprimeLength, // out + BYTE** capitalUprime, // out + TSS_DAA_IDENTITY_PROOF** identityProof, // out + TSS_DAA_JOIN_SESSION** joinSession) // out +{ + TSS_RESULT result; +#ifdef TSS_DEBUG + int before = mallinfo().uordblks; +#endif + + LogDebug("-> TSPI_TPM_DAA_joinInit hDAA=%x hTPM=%x daaCounter=%x issuerPk=%x", + (int)hDAA, (int)hTPM, daaCounter, (int)issuerPk); + result = Tspi_TPM_DAA_JoinInit_internal( + hDAA, + hTPM, + daaCounter, + (TSS_DAA_PK *)issuerPk, + issuerAuthPKsLength, + (RSA **)issuerAuthPKs, + issuerAuthPKSignaturesLength, + issuerAuthPKSignatures, + capitalUprimeLength, + capitalUprime, + identityProof, + joinSession); + bi_flush_memory(); + + LogDebug("TSPI_TPM_DAA_joinInit ALLOC DELTA:%d",mallinfo().uordblks-before); + LogDebug("<- TSPI_TPM_DAA_joinInit result=%d", result); + return result; +} +#else +TSS_RESULT +Tspi_TPM_DAA_JoinInit(TSS_HTPM hTPM, /* in */ + TSS_HDAA_ISSUER_KEY hIssuerKey, /* in */ + UINT32 daaCounter, /* in */ + UINT32 issuerAuthPKsLength, /* in */ + TSS_HKEY* issuerAuthPKs, /* in */ + UINT32 issuerAuthPKSignaturesLength, /* in */ + UINT32 issuerAuthPKSignaturesLength2, /* in */ + BYTE** issuerAuthPKSignatures, /* in */ + UINT32* capitalUprimeLength, /* out */ + BYTE** capitalUprime, /* out */ + TSS_DAA_IDENTITY_PROOF** identityProof, /* out */ + UINT32* joinSessionLength, /* out */ + BYTE** joinSession) /* out */ +{ + TSS_RESULT result; +#ifdef TSS_DEBUG + int before = mallinfo().uordblks; +#endif + + if (!capitalUprimeLength || !capitalUprime || !identityProof || !joinSessionLength || + !joinSession) + return TSPERR(TSS_E_BAD_PARAMETER); + + result = Tspi_TPM_DAA_JoinInit_internal(hTPM, hIssuerKey, daaCounter, issuerAuthPKsLength, + issuerAuthPKs, issuerAuthPKSignaturesLength, + issuerAuthPKSignaturesLength2, + issuerAuthPKSignatures, capitalUprimeLength, + capitalUprime, identityProof, joinSessionLength, + joinSession); + + bi_flush_memory(); + + LogDebug("TSPI_TPM_DAA_joinInit ALLOC DELTA:%d",mallinfo().uordblks-before); + LogDebug("<- TSPI_TPM_DAA_joinInit result=%d", result); + + return result; +} +#endif +/** +This function is part of the DAA Issuer component. It defines the generation of a DAA Issuer +public and secret key. Further it defines the generation of a non-interactive proof (using +the Fiat-Shamir heuristic) that the public keys were chosen correctly. The latter will guarantee +the security requirements of the platform (respectively, its user), i.e., that the privacy and +anonymity of signatures will hold. +The generation of the authentication keys of the DAA Issuer, which are used to authenticate +(main) DAA Issuer keys, is not defined by this function. +This is an optional function and does not require a TPM or a TCS. + +Parameters + - hDAA: Handle of the DAA object + - issuerBaseNameLength: Length of issuerBaseName + - issuerBaseName: Unique name of the DAA Issuer + - numberPlatformAttributes: Number of attributes that the Platform can choose and which + will not be visible to the Issuer. + - numberIssuerAttributes:Number of attributes that the Issuer can choose and which will + be visible to both the Platform and the Issuer. + - keyPair: Handle of the main DAA Issuer key pair (private and public portion) + - publicKeyProof:Handle of the proof of the main DAA Issuer public key +*/ +#if 0 +TSPICALL +Tspi_DAA_IssueSetup(TSS_HDAA hDAA, // in + UINT32 issuerBaseNameLength, // in + BYTE* issuerBaseName, // in + UINT32 numberPlatformAttributes, // in + UINT32 numberIssuerAttributes, // in + TSS_HDAA_DATA* keyPair, // out (TSS_KEY_PAIR) + TSS_HDAA_DATA* publicKeyProof) // out (TSS_DAA_PK_PROOF) +{ + TSS_RESULT result; + KEY_PAIR_WITH_PROOF_internal *key_proof; + TSS_DAA_KEY_PAIR *tss_daa_key_pair; + TSS_HCONTEXT hContext; +#ifdef TSS_DEBUG + int before = mallinfo().uordblks; +#endif + + LogDebug( "TSPI_DAA_IssueSetup hDAA=%d ",hDAA); + // TODO: lock access to _hContext + if ((result = obj_daa_get_tsp_context(hDAA, &hContext))) + return result; + result = generate_key_pair(numberIssuerAttributes, + numberPlatformAttributes, + issuerBaseNameLength, + issuerBaseName, + &key_proof); + if (result != TSS_SUCCESS) + return result; + LogDebug("TSPI_DAA_IssueSetup convert internal structure to public allocated using tspi_alloc"); + LogDebug("key_proof->proof->length_challenge=%d key_proof->proof->length_response=%d", + key_proof->proof->length_challenge, key_proof->proof->length_response); + // prepare out parameters + *publicKeyProof = i_2_e_TSS_DAA_PK_PROOF( key_proof->proof, &tss_alloc, hContext); + + tss_daa_key_pair = (TSS_DAA_KEY_PAIR *)tss_alloc( sizeof(TSS_DAA_KEY_PAIR), hContext); + if (tss_daa_key_pair == NULL) { + LogError("malloc of %d bytes failed", sizeof(TSS_DAA_KEY_PAIR)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + tss_daa_key_pair->private_key = i_2_e_TSS_DAA_PRIVATE_KEY( key_proof->private_key, + &tss_alloc, + hContext); + tss_daa_key_pair->public_key = i_2_e_TSS_DAA_PK( key_proof->pk, + &tss_alloc, + hContext); + *keyPair = (TSS_HKEY)tss_daa_key_pair; +close: + bi_flush_memory(); + + LogDebug("TSPI_DAA_IssueSetup ALLOC DELTA:%d", mallinfo().uordblks-before); + LogDebug( "TSPI_DAA_IssueSetup end return=%d ",result); + return result; +} +#else +TSS_RESULT +Tspi_DAA_Issuer_GenerateKey(TSS_HDAA_ISSUER_KEY hIssuerKey, // in + UINT32 issuerBaseNameLength, // in + BYTE* issuerBaseName) // in +{ + TSS_RESULT result; + KEY_PAIR_WITH_PROOF_internal *key_proof; + TSS_DAA_KEY_PAIR *tss_daa_key_pair; + TSS_HCONTEXT tspContext; + UINT32 numberPlatformAttributes, numberIssuerAttributes; +#ifdef TSS_DEBUG + int before = mallinfo().uordblks; +#endif + + if ((result = obj_daaissuerkey_get_tsp_context(hIssuerKey, &tspContext))) + return result; + + if ((result = obj_daaissuerkey_get_attribs(hIssuerKey, &numberIssuerAttributes, + &numberPlatformAttributes))) + return result; + + if ((result = generate_key_pair(numberIssuerAttributes, numberPlatformAttributes, + issuerBaseNameLength, issuerBaseName, &key_proof))) + return result; + + LogDebugFn("convert internal structure to public allocated using tspi_alloc"); + LogDebug("key_proof->proof->length_challenge=%d key_proof->proof->length_response=%d", + key_proof->proof->length_challenge, key_proof->proof->length_response); + + // prepare out parameters + *publicKeyProof = i_2_e_TSS_DAA_PK_PROOF( key_proof->proof, &tss_alloc, tspContext); + + tss_daa_key_pair = (TSS_DAA_KEY_PAIR *)tss_alloc( sizeof(TSS_DAA_KEY_PAIR), tspContext); + if (tss_daa_key_pair == NULL) { + LogError("malloc of %d bytes failed", sizeof(TSS_DAA_KEY_PAIR)); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto close; + } + tss_daa_key_pair->private_key = i_2_e_TSS_DAA_PRIVATE_KEY( key_proof->private_key, + &tss_alloc, + tspContext); + tss_daa_key_pair->public_key = i_2_e_TSS_DAA_PK( key_proof->pk, + &tss_alloc, + tspContext); + *keyPair = (TSS_HKEY)tss_daa_key_pair; +close: + bi_flush_memory(); + + LogDebug("TSPI_DAA_IssueSetup ALLOC DELTA:%d", mallinfo().uordblks-before); + LogDebug( "TSPI_DAA_IssueSetup end return=%d ",result); + return result; +} +#endif +/** +This function is part of the DAA Issuer component. It's the first function out of 2 in order to +issue a DAA Credential for a TCG Platform. It assumes that the endorsement key and its +associated credentials are from a genuine and valid TPM. (Verification of the credentials is + a process defined by the TCG Infrastructure WG.) +This is an optional function and does not require a TPM or a TCS. +*/ +TSPICALL +Tspi_DAA_IssueInit(TSS_HDAA hDAA, // in + TSS_HKEY issuerAuthPK, // in + TSS_HDAA_DATA issuerKeyPair, // in (TSS_DAA_KEY_PAIR) + TSS_DAA_IDENTITY_PROOF* identityProof, // in + UINT32 capitalUprimeLength, // in + BYTE* capitalUprime, // in + UINT32 daaCounter, // in + UINT32* nonceIssuerLength, // out + BYTE** nonceIssuer, // out + UINT32* authenticationChallengeLength, // out + BYTE** authenticationChallenge, // out + TSS_DAA_JOIN_ISSUER_SESSION** joinSession) // out +{ + TSS_RESULT result; +#ifdef TSS_DEBUG + int before = mallinfo().uordblks; +#endif + + LogDebug("Tspi_DAA_IssueInit_internal hDAA=%d daaCounter=%d", (int)hDAA, (int)daaCounter); + result = Tspi_DAA_IssueInit_internal( + hDAA, // in + issuerAuthPK, // in + issuerKeyPair, // in + identityProof, // in + capitalUprimeLength, // in + capitalUprime, // in + daaCounter, // in + nonceIssuerLength, // out + nonceIssuer, // out + authenticationChallengeLength, // out + authenticationChallenge, // out + joinSession // out + ); + bi_flush_memory(); + + LogDebug("Tspi_DAA_IssueInit_internal ALLOC DELTA:%d", mallinfo().uordblks-before); + + return result; +} + +/** +This function verifies the DAA public key of a DAA Issuer with respect to its associated proof. +This is a resource consuming task. It can be done by trusted third party (certification). +This is an optional function and does not require a TPM or a TCS. +Parameters: + - hDAA: Handle of the DAA object + - issuerPk: DAA Issuer public key + - issuerPkProof: Proofs the correctness of the DAA Issuer public key + - isCorrect: Proofs the correctness of the DAA Issuer public key +*/ +TSPICALL +Tspi_DAA_IssuerKeyVerification(TSS_HDAA hDAA, // in + TSS_HDAA_DATA issuerPk, // in (TSS_DAA_PK) + TSS_HDAA_DATA issuerPkProof, // in (TSS_DAA_PK_PROOF) + TSS_BOOL* isCorrect) // out +{ + TSS_RESULT result; + int is_correct; +#ifdef TSS_DEBUG + int before = mallinfo().uordblks; +#endif + + LogDebug("TSPI_DAA_IssuerKeyVerification hDAA=%ld issuerPk=%ld issuerPkProof=%ld", + (long)hDAA, (long)issuerPk, (long)issuerPkProof); + TSS_DAA_PK_internal *pk_internal = e_2_i_TSS_DAA_PK( (TSS_DAA_PK *)issuerPk); + TSS_DAA_PK_PROOF_internal *proof_internal = e_2_i_TSS_DAA_PK_PROOF( issuerPkProof); + LogDebug( "challenge=[%s]", dump_byte_array( proof_internal->length_challenge, + proof_internal->challenge)); + result = is_pk_correct( pk_internal, proof_internal, &is_correct ); + if( is_correct) *isCorrect = TRUE; + else *isCorrect = FALSE; + bi_flush_memory(); +#ifdef TSS_DEBUG + LogDebug("TSPI_DAA_IssuerKeyVerification ALLOC DELTA:%d", mallinfo().uordblks-before); +#endif + return result; +} + +/** +This function is part of the DAA Issuer component. It?s the last function out of 2 in order to +issue DAA Credential for a TCG Platform. It detects rogue TPM according to published rogue +TPM DAA keys. +This is an optional function and does not require a TPM or a TCS. +*/ +TSPICALL +Tspi_DAA_IssueCredential(TSS_HDAA hDAA, // in + UINT32 attributesIssuerLength, // in + BYTE** attributesIssuer, // in + TSS_DAA_CREDENTIAL_REQUEST* credentialRequest, // in + TSS_DAA_JOIN_ISSUER_SESSION* joinSession, // in + TSS_DAA_CRED_ISSUER** credIssuer) // out +{ + TSS_RESULT result; +#ifdef TSS_DEBUG + int before = mallinfo().uordblks; +#endif + + LogDebug("Tspi_DAA_IssueCredential hDAA=%d attributesIssuerLength=%d", + (int)hDAA, + (int)attributesIssuerLength); + result = Tspi_DAA_IssueCredential_internal( + hDAA, + attributesIssuerLength, + attributesIssuer, + credentialRequest, + joinSession, + credIssuer + ); + bi_flush_memory(); +#ifdef TSS_DEBUG + LogDebug("Tspi_DAA_IssueCredential ALLOC DELTA:%d", mallinfo().uordblks-before); +#endif + return result; +} + + +/** +This function is part of the DAA Verifier component. It is the first function out of 2 in order +to verify a DAA credential of a TCG platform. It creates a challenge for the TCG platform.last +function out of 2 in order to issue a This is an optional function and does not require a +TPM or a TCS. +*/ +TSPICALL +Tspi_DAA_VerifyInit(TSS_HDAA hDAA, // in + UINT32* nonceVerifierLength, // out + BYTE** nonceVerifier, // out + UINT32* baseNameLength, // out + BYTE** baseName) // out +{ + TSS_RESULT result; +#ifdef TSS_DEBUG + int before = mallinfo().uordblks; +#endif + + // TODO which interface to use ? with or without baseName ? + LogDebug("Tspi_DAA_VerifyInit hDAA=%d", (int)hDAA); + result = Tspi_DAA_VerifyInit_internal( hDAA, + nonceVerifierLength, + nonceVerifier, + baseNameLength, + baseName); + bi_flush_memory(); +#ifdef TSS_DEBUG + LogDebug("Tspi_DAA_VerifyInit ALLOC DELTA:%d", mallinfo().uordblks-before); +#endif + return result; +} + + +/** +This function is part of the DAA Verifier component. It is the last function out of 2 in +order to verify a DAA Credential of a TCG Platform. It verifies the DAA credential and +detects public rogue TPMs. This is an optional function and does not require a TPM +or a TCS. +*/ +TSPICALL +Tspi_DAA_VerifySignature(TSS_HDAA hDAA, // in + TSS_DAA_SIGNATURE* daaSignature, // in + TSS_HDAA_DATA hPubKeyIssuer, // in (TSS_DAA_PK) + TSS_DAA_SIGN_DATA* signData, // in + UINT32 attributesLength, // in + BYTE** attributes, // in + UINT32 nonceVerifierLength,// in + BYTE* nonceVerifier, // in + UINT32 baseNameLength, // in + BYTE* baseName, // in + TSS_BOOL* isCorrect) // out +{ + TSS_RESULT result; +#ifdef TSS_DEBUG + int before = mallinfo().uordblks; +#endif + + LogDebug("Tspi_DAA_VerifySignature hDAA=%d", (int)hDAA); + result = Tspi_DAA_VerifySignature_internal( hDAA, + daaSignature, + hPubKeyIssuer, + signData, + attributesLength, + attributes, + nonceVerifierLength, + nonceVerifier, + baseNameLength, + baseName, + isCorrect); + bi_flush_memory(); +#ifdef TSS_DEBUG + LogDebug("Tspi_DAA_VerifySignature ALLOC DELTA:%d", mallinfo().uordblks-before); +#endif + return result; +} + + +/** +This function is part of the DAA Issuer component. It is the last function out of 2 in +order to issue a DAA Credential for a TCG Platform. It detects rogue TPM according +to published rogue TPM DAA keys. +This is an optional function and does not require a TPM or a TCS. + +Parameters + - hDAA: Handle of the DAA object + - daaPublicKey: daaPublickKey + - keyPair: Public and private key of the DAA Anonymity Revocation Authority to encrypt + the pseudonym of a DAA Signature +*/ +TSPICALL +Tspi_DAA_RevokeSetup(TSS_HDAA hDAA, // in + TSS_HDAA_DATA daaPublicKey, // in + TSS_HDAA_DATA* arPublicKey, // out (TSS_DAA_AR_PK) + TSS_HDAA_DATA* arPrivateKey) // out (TSS_DAA_AR_SK) +{ + TSS_RESULT result; +#ifdef TSS_DEBUG + int before = mallinfo().uordblks; +#endif + + result = Tspi_DAA_RevokeSetup_internal( + hDAA, // in +//TODO: remove cast when the above interface is changed + daaPublicKey, // in + keyPair // out + ); + bi_flush_memory(); +#ifdef TSS_DEBUG + LogDebug("Tspi_DAA_RevokeSetup ALLOC DELTA:%d", mallinfo().uordblks-before); +#endif + return TSS_SUCCESS; +} + + +/** +This function is part of the DAA Anonymity Revocation Authority component. It defines the +Cramer-Shoup decryption algorithm to revoke the anonymity of a DAA Signature. The pseudonym, +with respect to either the DAA Verifier?s base name, the DAA Issuer?s base name or (just for +completeness) a random base name, can be revealed. +The pseudonym with respect to a DAA Signature and the used base name is V N . An encryption of +V N is the tuple (d1,d 2 ,d 3,d 4 ) and is decrypted using the secret key ( 0 5 x ,?, x ), the +decryption condition and the DAA public key. +This is an optional function and does not require a TPM or a TCS. + +Parameters: + - hDAA: Handle of the DAA object + - encryptedPseudonym: encryptedPseudonym + - decryptCondition: Condition for the decryption of the pseudonym. + - arPrivateKey: arPrivateKey + - daaPublicKey: daaPublicKey + - pseudonym: pseudonym +*/ +TSPICALL +Tspi_DAA_ARDecrypt(TSS_HDAA hDAA, // in + TSS_DAA_PSEUDONYM_ENCRYPTED* encryptedPseudonym, // in + TSS_HHASH decryptCondition, // in + TSS_HDAA_DATA arPrivateKey, // in (TSS_DAA_AR_SK) + TSS_HDAA_DATA daaPublicKey, // in (TSS_DAA_PK) + TSS_DAA_PSEUDONYM_PLAIN** pseudonym) // out +{ + TSS_RESULT result; +#ifdef TSS_DEBUG + int before = mallinfo().uordblks; +#endif + + result = Tspi_DAA_ARDecrypt_internal( + hDAA, // in + encryptedPseudonym, // in + decryptCondition, // in +//TODO: remove cast when the above interface is changed + (void *)arPrivateKey, // in + (void *)daaPublicKey, // in + pseudonym // out + ); + bi_flush_memory(); +#ifdef TSS_DEBUG + LogDebug("Tspi_DAA_ARDecrypt ALLOC DELTA:%d", mallinfo().uordblks-before); +#endif + return result; +} + +/** +This is the second out of 3 functions to execute in order to receive a DAA Credential. It +computes the credential request for the DAA Issuer, which also includes the Platform +DAA public key and the attributes that were chosen by the Platform, and which are not +visible to the DAA Issuer. The Platform can commit to the attribute values it has chosen. +*/ +TSPICALL +Tspi_TPM_DAA_JoinCreateDaaPubKey(TSS_HDAA hDAA, // in + TSS_HTPM hTPM, // in + UINT32 authenticationChallengeLength,// in + BYTE* authenticationChallenge, // in + UINT32 nonceIssuerLength, // in + BYTE* nonceIssuer, // in + UINT32 attributesPlatformLength, // in + BYTE** attributesPlatform, // in + TSS_DAA_JOIN_SESSION* joinSession, // in, out + TSS_DAA_CREDENTIAL_REQUEST** credentialRequest) // out +{ + TSS_RESULT result; +#ifdef TSS_DEBUG + int before = mallinfo().uordblks; +#endif + + LogDebug("Tspi_TPM_DAA_JoinCreateDaaPubKey hDAA=%d joinSession=%d", + (int)hDAA, (int)joinSession); + result = Tspi_TPM_DAA_JoinCreateDaaPubKey_internal( + hDAA, // in + hTPM, // in + authenticationChallengeLength, // in + authenticationChallenge, // in + nonceIssuerLength, // in + nonceIssuer, // in + attributesPlatformLength, // in + attributesPlatform, // in + joinSession, // in, out + credentialRequest // out + ); + bi_flush_memory(); +#ifdef TSS_DEBUG + LogDebug("Tspi_TPM_DAA_JoinCreateDaaPubKey ALLOC DELTA:%d", mallinfo().uordblks-before); +#endif + return result; +} + + +/** +This is the last out of 3 functions to execute in order to receive a DAA Credential. +It verifies the issued credential from the DAA Issuer and computes the final DAA Credential. +*/ +TSPICALL +Tspi_TPM_DAA_JoinStoreCredential(TSS_HDAA hDAA, // in + TSS_HTPM hTPM, // in + TSS_DAA_CRED_ISSUER* credIssuer, // in + TSS_DAA_JOIN_SESSION* joinSession, // in + TSS_HDAA_DATA* phDaaCredential) // out (TSS_DAA_CREDENTIAL) +{ + TSS_RESULT result; +#ifdef TSS_DEBUG + int before = mallinfo().uordblks; +#endif + + LogDebug("Tspi_TPM_DAA_JoinStoreCredential hDAA=%d credIssuer=%d joinSession=%d", + (int)hDAA, (int)&credIssuer, (int)&joinSession); + result = Tspi_TPM_DAA_JoinStoreCredential_internal(hDAA, + hTPM, + credIssuer, + joinSession, + phDaaCredential); + bi_flush_memory(); +#ifdef TSS_DEBUG + LogDebug("Tspi_TPM_DAA_JoinStoreCredential ALLOC DELTA:%d", mallinfo().uordblks-before); +#endif + return result; +} + + +/** +This function creates a DAA Signature that proofs ownership of the DAA Credential and +includes a signature on either a public AIK or a message. +If anonymity revocation is enabled, the value Nv is not provided in the clear anymore but +encrypted under the public key of anonymity revocation authority, a trusted third party (TTP). +Thus the DAA Verifier cannot check for revocation or link a transaction/signature to prior ones. +Depending on how z is chosen, the protocol either allows to implementing anonymity revocation +(i.e., using the DAA Issuer long-term base name bsn I as the DAA Verifier base name bsnV ), or +having the TTP doing the linking of different signatures for the same DAA Verifier (i.e., +using the DAA Verifier base name ). +*/ +TSPICALL +Tspi_TPM_DAA_Sign(TSS_HDAA hDAA, // in + TSS_HTPM hTPM, // in + TSS_HDAA_DATA hDaaCredential, // in (TSS_DAA_CREDENTIAL) + TSS_DAA_SELECTED_ATTRIB* revealAttributes, // in + UINT32 verifierBaseNameLength, // in + BYTE* verifierBaseName, // in + UINT32 verifierNonceLength, // in + BYTE* verifierNonce, // in + TSS_DAA_SIGN_DATA* signData, // in + TSS_DAA_SIGNATURE** daaSignature) // out +{ + TSS_RESULT result; +#ifdef TSS_DEBUG + int before = mallinfo().uordblks; +#endif + + LogDebug("-> TSPI_TPM_DAA_Sign hDAA=%ld hTPM=%ld ", (long)hDAA, (long)hTPM); + + result = Tspi_TPM_DAA_Sign_internal(hDAA, + hTPM, + hDaaCredential, + revealAttributes, + verifierBaseNameLength, + verifierBaseName, + verifierNonceLength, + verifierNonce, + signData, + daaSignature); + bi_flush_memory(); +#ifdef TSS_DEBUG + LogDebug("TSPI_TPM_DAA_joinInit ALLOC DELTA:%d", mallinfo().uordblks-before); +#endif + LogDebug("<- TSPI_TPM_DAA_joinInit result=%d", result); + return result; +} diff --git a/src/tspi/tspi_delegate.c b/src/tspi/tspi_delegate.c new file mode 100644 index 0000000..c8fcb6a --- /dev/null +++ b/src/tspi/tspi_delegate.c @@ -0,0 +1,470 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "obj.h" +#include "tsp_delegate.h" +#include "tsplog.h" + + +TSS_RESULT +Tspi_TPM_Delegate_AddFamily(TSS_HTPM hTpm, /* in, must not be NULL */ + BYTE bLabel, /* in */ + TSS_HDELFAMILY* phFamily) /* out */ +{ + TPM_FAMILY_ID familyID = 0; + UINT32 outDataSize; + BYTE *outData = NULL; + UINT64 offset; + TSS_RESULT result; + + if (phFamily == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + *phFamily = NULL_HDELFAMILY; + + if ((result = do_delegate_manage(hTpm, familyID, TPM_FAMILY_CREATE, sizeof(bLabel), &bLabel, + &outDataSize, &outData))) + return result; + + offset = 0; + Trspi_UnloadBlob_UINT32(&offset, &familyID, outData); + + /* Create or update the delfamily object */ + if ((result = update_delfamily_object(hTpm, familyID))) + goto done; + + obj_delfamily_find_by_familyid(hTpm, familyID, phFamily); + if (*phFamily == NULL_HDELFAMILY) + result = TSPERR(TSS_E_INTERNAL_ERROR); + +done: + free(outData); + + return result; +} + +TSS_RESULT +Tspi_TPM_Delegate_GetFamily(TSS_HTPM hTpm, /* in, must not NULL */ + UINT32 ulFamilyID, /* in */ + TSS_HDELFAMILY* phFamily) /* out */ +{ + TSS_RESULT result; + + if (phFamily == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + *phFamily = NULL_HDELFAMILY; + + /* Update the delfamily object */ + if ((result = update_delfamily_object(hTpm, ulFamilyID))) + return result; + + obj_delfamily_find_by_familyid(hTpm, ulFamilyID, phFamily); + if (*phFamily == NULL_HDELFAMILY) + result = TSPERR(TSS_E_BAD_PARAMETER); + + return result; +} + +TSS_RESULT +Tspi_TPM_Delegate_InvalidateFamily(TSS_HTPM hTpm, /* in, must not be NULL */ + TSS_HDELFAMILY hFamily) /* in */ +{ + TPM_FAMILY_ID familyID; + UINT32 outDataSize; + BYTE *outData = NULL; + TSS_RESULT result; + + if ((result = obj_delfamily_get_familyid(hFamily, &familyID))) + return result; + + if ((result = do_delegate_manage(hTpm, familyID, TPM_FAMILY_INVALIDATE, 0, NULL, + &outDataSize, &outData))) + return result; + + /* Delete the delfamily object */ + result = obj_delfamily_remove(hFamily, hTpm); + + free(outData); + + return result; +} + +TSS_RESULT +Tspi_TPM_Delegate_CreateDelegation(TSS_HOBJECT hObject, /* in */ + BYTE bLabel, /* in */ + UINT32 ulFlags, /* in */ + TSS_HPCRS hPcrs, /* in */ + TSS_HDELFAMILY hFamily, /* in */ + TSS_HPOLICY hDelegation) /* in, out */ +{ + TSS_RESULT result; + + if (obj_is_tpm(hObject)) { + if ((result = create_owner_delegation(hObject, bLabel, ulFlags, hPcrs, hFamily, + hDelegation))) + return result; + } else if (obj_is_rsakey(hObject)) { + if ((result = create_key_delegation(hObject, bLabel, ulFlags, hPcrs, hFamily, + hDelegation))) + return result; + } else + return TSPERR(TSS_E_INVALID_HANDLE); + + return TSS_SUCCESS; +} + +TSS_RESULT +Tspi_TPM_Delegate_CacheOwnerDelegation(TSS_HTPM hTpm, /* in */ + TSS_HPOLICY hDelegation, /* in */ + UINT32 ulIndex, /* in */ + UINT32 ulFlags) /* in */ +{ + TSS_HCONTEXT hContext; + TSS_HPOLICY hPolicy; + UINT32 blobSize; + BYTE *blob = NULL; + UINT32 secretMode = TSS_SECRET_MODE_NONE; + Trspi_HashCtx hashCtx; + TCPA_DIGEST digest; + TPM_AUTH ownerAuth, *pAuth; + TSS_RESULT result; + + if ((result = obj_tpm_get_tsp_context(hTpm, &hContext))) + return result; + + if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy))) + return result; + + if ((result = obj_policy_get_delegation_blob(hDelegation, TSS_DELEGATIONTYPE_OWNER, + &blobSize, &blob))) + return result; + + if (ulFlags & ~TSS_DELEGATE_CACHEOWNERDELEGATION_OVERWRITEEXISTING) { + result = TSPERR(TSS_E_BAD_PARAMETER); + goto done; + } + + if ((ulFlags & TSS_DELEGATE_CACHEOWNERDELEGATION_OVERWRITEEXISTING) == 0) { + TPM_DELEGATE_PUBLIC public; + + /* Verify there is nothing occupying the specified row */ + result = get_delegate_index(hContext, ulIndex, &public); + if (result == TSS_SUCCESS) { + free(public.pcrInfo.pcrSelection.pcrSelect); + result = TSPERR(TSS_E_DELFAMILY_ROWEXISTS); + goto done; + } + } + + if (hPolicy != NULL_HPOLICY) { + if ((result = obj_policy_get_mode(hPolicy, &secretMode))) + goto done; + } + + if (secretMode != TSS_SECRET_MODE_NONE) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_LoadOwnerDelegation); + result |= Trspi_Hash_UINT32(&hashCtx, ulIndex); + result |= Trspi_Hash_UINT32(&hashCtx, blobSize); + result |= Trspi_HashUpdate(&hashCtx, blobSize, blob); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + pAuth = &ownerAuth; + if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_Delegate_LoadOwnerDelegation, + hPolicy, FALSE, &digest, pAuth))) + goto done; + } else + pAuth = NULL; + + if ((result = TCS_API(hContext)->Delegate_LoadOwnerDelegation(hContext, ulIndex, blobSize, + blob, pAuth))) + goto done; + + if (pAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_LoadOwnerDelegation); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth))) + goto done; + } + + result = obj_policy_set_delegation_index(hDelegation, ulIndex); + +done: + free_tspi(hContext, blob); + + return result; +} + +TSS_RESULT +Tspi_TPM_Delegate_UpdateVerificationCount(TSS_HTPM hTpm, /* in */ + TSS_HPOLICY hDelegation) /* in, out */ +{ + TSS_HCONTEXT hContext; + TSS_HPOLICY hPolicy; + UINT32 secretMode = TSS_SECRET_MODE_NONE; + Trspi_HashCtx hashCtx; + TCPA_DIGEST digest; + TPM_AUTH ownerAuth, *pAuth; + TSS_BOOL indexSet; + UINT32 inputSize; + BYTE *input = NULL; + UINT32 outputSize; + BYTE *output = NULL; + UINT64 offset; + TSS_RESULT result; + + if ((result = obj_tpm_get_tsp_context(hTpm, &hContext))) + return result; + + if ((result = obj_tpm_get_policy(hTpm, TSS_POLICY_USAGE, &hPolicy))) + return result; + + if (hPolicy != NULL_HPOLICY) { + if ((result = obj_policy_get_mode(hPolicy, &secretMode))) + goto done; + } + + if ((result = obj_policy_is_delegation_index_set(hDelegation, &indexSet))) + return result; + if (indexSet) { + UINT32 index; + + if ((result = obj_policy_get_delegation_index(hDelegation, &index))) + return result; + inputSize = sizeof(UINT32); + input = calloc_tspi(hContext, inputSize); + if (!input) { + LogError("malloc of %zd bytes failed.", sizeof(UINT32)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + offset = 0; + Trspi_LoadBlob_UINT32(&offset, index, input); + } else { + if ((result = obj_policy_get_delegation_blob(hDelegation, 0, + &inputSize, &input))) + return result; + } + + if (secretMode != TSS_SECRET_MODE_NONE) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_UpdateVerification); + result |= Trspi_Hash_UINT32(&hashCtx, inputSize); + result |= Trspi_HashUpdate(&hashCtx, inputSize, input); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + pAuth = &ownerAuth; + if ((result = secret_PerformAuth_OIAP(hTpm, TPM_ORD_Delegate_UpdateVerification, + hPolicy, FALSE, &digest, pAuth))) + goto done; + } else + pAuth = NULL; + + if ((result = TCS_API(hContext)->Delegate_UpdateVerificationCount(hContext, inputSize, + input, pAuth, &outputSize, + &output))) + goto done; + + if (pAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Delegate_UpdateVerification); + result |= Trspi_Hash_UINT32(&hashCtx, outputSize); + result |= Trspi_HashUpdate(&hashCtx, outputSize, output); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth))) + goto done; + } + + result = obj_policy_set_delegation_blob(hDelegation, 0, outputSize, output); + +done: + free_tspi(hContext, input); + free(output); + + return result; +} + +TSS_RESULT +Tspi_TPM_Delegate_VerifyDelegation(TSS_HPOLICY hDelegation) /* in, out */ +{ + TSS_HCONTEXT hContext; + UINT32 delegateSize; + BYTE *delegate = NULL; + TSS_RESULT result; + + if ((result = obj_policy_get_tsp_context(hDelegation, &hContext))) + return result; + + if ((result = obj_policy_get_delegation_blob(hDelegation, 0, &delegateSize, &delegate))) + return result; + + result = TCS_API(hContext)->Delegate_VerifyDelegation(hContext, delegateSize, delegate); + + free_tspi(hContext, delegate); + + return result; +} + +TSS_RESULT +Tspi_TPM_Delegate_ReadTables(TSS_HCONTEXT hContext, /* in */ + UINT32* pulFamilyTableSize, /* out */ + TSS_FAMILY_TABLE_ENTRY** ppFamilyTable, /* out */ + UINT32* pulDelegateTableSize, /* out */ + TSS_DELEGATION_TABLE_ENTRY** ppDelegateTable) /* out */ +{ + UINT32 tpmFamilyTableSize, tpmDelegateTableSize; + BYTE *tpmFamilyTable = NULL, *tpmDelegateTable = NULL; + TPM_FAMILY_TABLE_ENTRY tpmFamilyEntry; + TSS_FAMILY_TABLE_ENTRY tssFamilyEntry, *tssFamilyTable = NULL; + UINT32 tssFamilyTableSize = 0; + TPM_DELEGATE_PUBLIC tpmDelegatePublic; + TSS_DELEGATION_TABLE_ENTRY tssDelegateEntry, *tssDelegateTable = NULL; + UINT32 tssDelegateTableSize = 0; + UINT32 tableIndex; + UINT64 tpmOffset; + UINT64 tssOffset; + TSS_RESULT result; + + if (!pulFamilyTableSize || !ppFamilyTable || !pulDelegateTableSize || !ppDelegateTable) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (!obj_is_context(hContext)) + return TSPERR(TSS_E_INVALID_HANDLE); + + if ((result = TCS_API(hContext)->Delegate_ReadTable(hContext, &tpmFamilyTableSize, + &tpmFamilyTable, &tpmDelegateTableSize, + &tpmDelegateTable))) + return result; + + if (tpmFamilyTableSize > 0) { + /* Create the TSS_FAMILY_TABLE_ENTRY array */ + for (tpmOffset = 0, tssOffset = 0; tpmOffset < tpmFamilyTableSize;) { + Trspi_UnloadBlob_TPM_FAMILY_TABLE_ENTRY(&tpmOffset, tpmFamilyTable, + &tpmFamilyEntry); + + /* No pointers in the family table entries, so no + assignments required before doing LoadBlob */ + Trspi_LoadBlob_TSS_FAMILY_TABLE_ENTRY(&tssOffset, NULL, &tssFamilyEntry); + } + + if ((tssFamilyTable = calloc_tspi(hContext, tssOffset)) == NULL) { + LogError("malloc of %" PRIu64 " bytes failed.", tssOffset); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + for (tpmOffset = 0, tssOffset = 0; tpmOffset < tpmFamilyTableSize; tssFamilyTableSize++) { + Trspi_UnloadBlob_TPM_FAMILY_TABLE_ENTRY(&tpmOffset, tpmFamilyTable, + &tpmFamilyEntry); + + tssFamilyEntry.familyID = tpmFamilyEntry.familyID; + tssFamilyEntry.label = tpmFamilyEntry.label.label; + tssFamilyEntry.verificationCount = tpmFamilyEntry.verificationCount; + tssFamilyEntry.enabled = + (tpmFamilyEntry.flags & TPM_FAMFLAG_ENABLE) ? TRUE : FALSE; + tssFamilyEntry.locked = + (tpmFamilyEntry.flags & TPM_FAMFLAG_DELEGATE_ADMIN_LOCK) ? TRUE : FALSE; + Trspi_LoadBlob_TSS_FAMILY_TABLE_ENTRY(&tssOffset, (BYTE *)tssFamilyTable, + &tssFamilyEntry); + } + } + + if (tpmDelegateTableSize > 0) { + /* Create the TSS_DELEGATION_TABLE_ENTRY array */ + for (tpmOffset = 0, tssOffset = 0; tpmOffset < tpmDelegateTableSize;) { + Trspi_UnloadBlob_UINT32(&tpmOffset, &tableIndex, tpmDelegateTable); + if ((result = Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC(&tpmOffset, tpmDelegateTable, + &tpmDelegatePublic))) { + free_tspi(hContext, tssFamilyTable); + goto done; + } + + /* Some pointers in the delegate table entries, so + do some assignments before doing LoadBlob */ + tssDelegateEntry.pcrInfo.sizeOfSelect = + tpmDelegatePublic.pcrInfo.pcrSelection.sizeOfSelect; + tssDelegateEntry.pcrInfo.selection = + tpmDelegatePublic.pcrInfo.pcrSelection.pcrSelect; + tssDelegateEntry.pcrInfo.sizeOfDigestAtRelease = + sizeof(tpmDelegatePublic.pcrInfo.digestAtRelease.digest); + tssDelegateEntry.pcrInfo.digestAtRelease = + tpmDelegatePublic.pcrInfo.digestAtRelease.digest; + Trspi_LoadBlob_TSS_DELEGATION_TABLE_ENTRY(&tssOffset, NULL, + &tssDelegateEntry); + + free(tpmDelegatePublic.pcrInfo.pcrSelection.pcrSelect); + } + + if ((tssDelegateTable = calloc_tspi(hContext, tssOffset)) == NULL) { + LogError("malloc of %" PRIu64 " bytes failed.", tssOffset); + free_tspi(hContext, tssFamilyTable); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + for (tpmOffset = 0, tssOffset = 0; tpmOffset < tpmDelegateTableSize; tssDelegateTableSize++) { + Trspi_UnloadBlob_UINT32(&tpmOffset, &tableIndex, tpmDelegateTable); + if ((result = Trspi_UnloadBlob_TPM_DELEGATE_PUBLIC(&tpmOffset, + tpmDelegateTable, &tpmDelegatePublic))) { + free_tspi(hContext, tssFamilyTable); + free_tspi(hContext, tssDelegateTable); + goto done; + } + + tssDelegateEntry.tableIndex = tableIndex; + tssDelegateEntry.label = tpmDelegatePublic.label.label; + tssDelegateEntry.pcrInfo.sizeOfSelect = + tpmDelegatePublic.pcrInfo.pcrSelection.sizeOfSelect; + tssDelegateEntry.pcrInfo.selection = + tpmDelegatePublic.pcrInfo.pcrSelection.pcrSelect; + tssDelegateEntry.pcrInfo.localityAtRelease = + tpmDelegatePublic.pcrInfo.localityAtRelease; + tssDelegateEntry.pcrInfo.sizeOfDigestAtRelease = + sizeof(tpmDelegatePublic.pcrInfo.digestAtRelease.digest); + tssDelegateEntry.pcrInfo.digestAtRelease = + tpmDelegatePublic.pcrInfo.digestAtRelease.digest; + tssDelegateEntry.per1 = tpmDelegatePublic.permissions.per1; + tssDelegateEntry.per2 = tpmDelegatePublic.permissions.per2; + tssDelegateEntry.familyID = tpmDelegatePublic.familyID; + tssDelegateEntry.verificationCount = tpmDelegatePublic.verificationCount; + Trspi_LoadBlob_TSS_DELEGATION_TABLE_ENTRY(&tssOffset, + (BYTE *)tssDelegateTable, &tssDelegateEntry); + + free(tpmDelegatePublic.pcrInfo.pcrSelection.pcrSelect); + } + } + + *ppFamilyTable = tssFamilyTable; + *pulFamilyTableSize = tssFamilyTableSize; + *ppDelegateTable = tssDelegateTable; + *pulDelegateTableSize = tssDelegateTableSize; + +done: + free(tpmFamilyTable); + free(tpmDelegateTable); + + return result; +} + diff --git a/src/tspi/tspi_dir.c b/src/tspi/tspi_dir.c new file mode 100644 index 0000000..10c0c38 --- /dev/null +++ b/src/tspi/tspi_dir.c @@ -0,0 +1,105 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_TPM_DirWrite(TSS_HTPM hTPM, /* in */ + UINT32 ulDirIndex, /* in */ + UINT32 ulDirDataLength, /* in */ + BYTE * rgbDirData) /* in */ +{ + TSS_HCONTEXT tspContext; + TCPA_RESULT result; + TPM_AUTH auth; + TCPA_DIGEST hashDigest; + TSS_HPOLICY hPolicy; + TCPA_DIRVALUE dirValue = { { 0 } }; + Trspi_HashCtx hashCtx; + + if (rgbDirData == NULL && ulDirDataLength != 0) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (ulDirDataLength > (UINT32)sizeof(TCPA_DIRVALUE)) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy))) + return result; + + memcpy((BYTE *)&dirValue, rgbDirData, ulDirDataLength); + + /* hash to be used for the OIAP calc */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_DirWriteAuth); + result |= Trspi_Hash_UINT32(&hashCtx, ulDirIndex); + result |= Trspi_HashUpdate(&hashCtx, (UINT32)sizeof(TCPA_DIRVALUE), (BYTE *)&dirValue); + if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) + return result; + + /* hashDigest now has the hash result */ + if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_DirWriteAuth, hPolicy, FALSE, + &hashDigest, &auth))) + return result; + + if ((result = TCS_API(tspContext)->DirWriteAuth(tspContext, ulDirIndex, &dirValue, &auth))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_DirWriteAuth); + if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) + return result; + + return obj_policy_validate_auth_oiap(hPolicy, &hashDigest, &auth); +} + +TSS_RESULT +Tspi_TPM_DirRead(TSS_HTPM hTPM, /* in */ + UINT32 ulDirIndex, /* in */ + UINT32 * pulDirDataLength, /* out */ + BYTE ** prgbDirData) /* out */ +{ + TCPA_DIRVALUE dirValue; + TSS_RESULT result; + TSS_HCONTEXT tspContext; + + if (pulDirDataLength == NULL || prgbDirData == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if ((result = TCS_API(tspContext)->DirRead(tspContext, ulDirIndex, &dirValue))) + return result; + + *pulDirDataLength = 20; + *prgbDirData = calloc_tspi(tspContext, *pulDirDataLength); + if (*prgbDirData == NULL) { + LogError("malloc of %d bytes failed.", *pulDirDataLength); + return TSPERR(TSS_E_OUTOFMEMORY); + } + memcpy(*prgbDirData, dirValue.digest, *pulDirDataLength); + return TSS_SUCCESS; +} diff --git a/src/tspi/tspi_ek.c b/src/tspi/tspi_ek.c new file mode 100644 index 0000000..d1b2065 --- /dev/null +++ b/src/tspi/tspi_ek.c @@ -0,0 +1,438 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_TPM_CreateEndorsementKey(TSS_HTPM hTPM, /* in */ + TSS_HKEY hKey, /* in */ + TSS_VALIDATION * pValidationData) /* in, out */ +{ + TCPA_NONCE antiReplay; + TCPA_DIGEST digest; + TSS_RESULT result; + UINT32 ekSize; + BYTE *ek; + TSS_KEY dummyKey; + UINT64 offset; + TCPA_DIGEST hash; + UINT32 newEKSize; + BYTE *newEK; + TSS_HCONTEXT tspContext; + TCPA_PUBKEY pubEK; + Trspi_HashCtx hashCtx; + + memset(&pubEK, 0, sizeof(TCPA_PUBKEY)); + memset(&dummyKey, 0, sizeof(TSS_KEY)); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if ((result = obj_rsakey_get_blob(hKey, &ekSize, &ek))) + return result; + + offset = 0; + if ((result = UnloadBlob_TSS_KEY(&offset, ek, &dummyKey))) + return result; + + offset = 0; + Trspi_LoadBlob_KEY_PARMS(&offset, ek, &dummyKey.algorithmParms); + free_key_refs(&dummyKey); + ekSize = offset; + + if (pValidationData == NULL) { + if ((result = get_local_random(tspContext, FALSE, sizeof(TCPA_NONCE), + (BYTE **)antiReplay.nonce))) { + LogError("Failed to create random nonce"); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + } else { + if (pValidationData->ulExternalDataLength < sizeof(antiReplay.nonce)) + return TSPERR(TSS_E_BAD_PARAMETER); + + memcpy(antiReplay.nonce, pValidationData->rgbExternalData, + sizeof(antiReplay.nonce)); + } + + if ((result = TCS_API(tspContext)->CreateEndorsementKeyPair(tspContext, antiReplay, ekSize, + ek, &newEKSize, &newEK, + &digest))) + return result; + + if (pValidationData == NULL) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_HashUpdate(&hashCtx, newEKSize, newEK); + result |= Trspi_HashUpdate(&hashCtx, TCPA_SHA1_160_HASH_LEN, antiReplay.nonce); + if ((result |= Trspi_HashFinal(&hashCtx, hash.digest))) + goto done; + + if (memcmp(hash.digest, digest.digest, TCPA_SHA1_160_HASH_LEN)) { + LogError("Internal verification failed"); + result = TSPERR(TSS_E_EK_CHECKSUM); + goto done; + } + } else { + pValidationData->rgbData = calloc_tspi(tspContext, newEKSize); + if (pValidationData->rgbData == NULL) { + LogError("malloc of %u bytes failed.", newEKSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + pValidationData->ulDataLength = newEKSize; + memcpy(pValidationData->rgbData, newEK, newEKSize); + memcpy(&pValidationData->rgbData[ekSize], antiReplay.nonce, + sizeof(antiReplay.nonce)); + + pValidationData->rgbValidationData = calloc_tspi(tspContext, + TCPA_SHA1_160_HASH_LEN); + if (pValidationData->rgbValidationData == NULL) { + LogError("malloc of %d bytes failed.", TCPA_SHA1_160_HASH_LEN); + free_tspi(tspContext, pValidationData->rgbData); + pValidationData->rgbData = NULL; + pValidationData->ulDataLength = 0; + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + pValidationData->ulValidationDataLength = TCPA_SHA1_160_HASH_LEN; + memcpy(pValidationData->rgbValidationData, digest.digest, TCPA_SHA1_160_HASH_LEN); + } + + if ((result = obj_rsakey_set_pubkey(hKey, FALSE, newEK)) && pValidationData) { + free_tspi(tspContext, pValidationData->rgbValidationData); + free_tspi(tspContext, pValidationData->rgbData); + pValidationData->rgbData = NULL; + pValidationData->ulDataLength = 0; + pValidationData->rgbValidationData = NULL; + pValidationData->ulValidationDataLength = 0; + } + +done: + free(newEK); + + return result; +} + +TSS_RESULT +Tspi_TPM_GetPubEndorsementKey(TSS_HTPM hTPM, /* in */ + TSS_BOOL fOwnerAuthorized, /* in */ + TSS_VALIDATION *pValidationData, /* in, out */ + TSS_HKEY *phEndorsementPubKey) /* out */ +{ + TCPA_DIGEST digest; + TSS_RESULT result; + UINT64 offset; + UINT32 pubEKSize; + BYTE *pubEK; + TCPA_NONCE antiReplay; + TCPA_DIGEST checkSum; + TSS_HOBJECT retKey; + TSS_HCONTEXT tspContext; + TCPA_PUBKEY pubKey; + Trspi_HashCtx hashCtx; + + memset(&pubKey, 0, sizeof(TCPA_PUBKEY)); + + if (phEndorsementPubKey == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if (fOwnerAuthorized) + return owner_get_pubek(tspContext, hTPM, phEndorsementPubKey); + + if (pValidationData == NULL) { + if ((result = get_local_random(tspContext, FALSE, sizeof(TCPA_NONCE), + (BYTE **)antiReplay.nonce))) { + LogDebug("Failed to generate random nonce"); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + } else { + if (pValidationData->ulExternalDataLength < sizeof(antiReplay.nonce)) + return TSPERR(TSS_E_BAD_PARAMETER); + + memcpy(antiReplay.nonce, pValidationData->rgbExternalData, + sizeof(antiReplay.nonce)); + } + + /* call down to the TPM */ + if ((result = TCS_API(tspContext)->ReadPubek(tspContext, antiReplay, &pubEKSize, &pubEK, + &checkSum))) + return result; + + /* validate the returned hash, or set up the return so that the user can */ + if (pValidationData == NULL) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_HashUpdate(&hashCtx, pubEKSize, pubEK); + result |= Trspi_HashUpdate(&hashCtx, TPM_SHA1_160_HASH_LEN, antiReplay.nonce); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + /* check validation of the entire pubkey structure */ + if (memcmp(digest.digest, checkSum.digest, TPM_SHA1_160_HASH_LEN)) { + /* validation failed, unload the pubEK in order to hash + * just the pubKey portion of the pubEK. This is done on + * Atmel chips specifically. + */ + offset = 0; + memset(&pubKey, 0, sizeof(TCPA_PUBKEY)); + if ((result = Trspi_UnloadBlob_PUBKEY(&offset, pubEK, &pubKey))) + goto done; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_HashUpdate(&hashCtx, pubKey.pubKey.keyLength, + pubKey.pubKey.key); + result |= Trspi_HashUpdate(&hashCtx, TPM_SHA1_160_HASH_LEN, + antiReplay.nonce); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if (memcmp(digest.digest, checkSum.digest, TCPA_SHA1_160_HASH_LEN)) { + result = TSPERR(TSS_E_EK_CHECKSUM); + goto done; + } + } + } else { + /* validate the entire TCPA_PUBKEY structure */ + pValidationData->ulDataLength = pubEKSize + TCPA_SHA1_160_HASH_LEN; + pValidationData->rgbData = calloc_tspi(tspContext, + pValidationData->ulDataLength); + if (pValidationData->rgbData == NULL) { + LogError("malloc of %u bytes failed.", + pValidationData->ulDataLength); + pValidationData->ulDataLength = 0; + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + memcpy(pValidationData->rgbData, pubEK, pubEKSize); + memcpy(&pValidationData->rgbData[pubEKSize], antiReplay.nonce, + TCPA_SHA1_160_HASH_LEN); + + pValidationData->ulValidationDataLength = TCPA_SHA1_160_HASH_LEN; + pValidationData->rgbValidationData = calloc_tspi(tspContext, + TCPA_SHA1_160_HASH_LEN); + if (pValidationData->rgbValidationData == NULL) { + LogError("malloc of %d bytes failed.", TCPA_SHA1_160_HASH_LEN); + pValidationData->ulValidationDataLength = 0; + pValidationData->ulDataLength = 0; + free_tspi(tspContext,pValidationData->rgbData); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + + memcpy(pValidationData->rgbValidationData, checkSum.digest, + TPM_SHA1_160_HASH_LEN); + } + + if ((result = obj_rsakey_add(tspContext, TSS_KEY_SIZE_2048|TSS_KEY_TYPE_LEGACY, &retKey))) + goto done; + + if ((result = obj_rsakey_set_pubkey(retKey, TRUE, pubEK))) + goto done; + + *phEndorsementPubKey = retKey; + +done: + free(pubEK); + return result; +} + +#ifdef TSS_BUILD_TSS12 +TSS_RESULT +Tspi_TPM_CreateRevocableEndorsementKey(TSS_HTPM hTPM, /* in */ + TSS_HKEY hKey, /* in */ + TSS_VALIDATION * pValidationData,/* in, out */ + UINT32 * pulEkResetDataLength, /* in, out */ + BYTE ** prgbEkResetData) /* in, out */ +{ + TPM_NONCE antiReplay; + TPM_DIGEST digest; + TSS_RESULT result; + UINT32 ekSize; + BYTE *ek; + TSS_KEY dummyKey; + UINT64 offset; + TSS_BOOL genResetAuth; + TPM_DIGEST eKResetAuth; + TPM_DIGEST hash; + UINT32 newEKSize; + BYTE *newEK; + TSS_HCONTEXT tspContext; + TPM_PUBKEY pubEK; + Trspi_HashCtx hashCtx; + + memset(&pubEK, 0, sizeof(TPM_PUBKEY)); + memset(&dummyKey, 0, sizeof(TSS_KEY)); + memset(&eKResetAuth, 0xff, sizeof(eKResetAuth)); + + if (!pulEkResetDataLength || !prgbEkResetData) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (*pulEkResetDataLength != 0) { + if (*prgbEkResetData == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (*pulEkResetDataLength < sizeof(eKResetAuth.digest)) + return TSPERR(TSS_E_BAD_PARAMETER); + + memcpy(eKResetAuth.digest, *prgbEkResetData, sizeof(eKResetAuth.digest)); + genResetAuth = FALSE; + } else { + if (*prgbEkResetData != NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + genResetAuth = TRUE; + } + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if ((result = obj_rsakey_get_blob(hKey, &ekSize, &ek))) + return result; + + offset = 0; + if ((result = UnloadBlob_TSS_KEY(&offset, ek, &dummyKey))) + return result; + + offset = 0; + Trspi_LoadBlob_KEY_PARMS(&offset, ek, &dummyKey.algorithmParms); + free_key_refs(&dummyKey); + ekSize = offset; + + if (pValidationData == NULL) { + if ((result = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE), + (BYTE **)antiReplay.nonce))) { + LogError("Failed to create random nonce"); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + } else { + if (pValidationData->ulExternalDataLength < sizeof(antiReplay.nonce)) + return TSPERR(TSS_E_BAD_PARAMETER); + + memcpy(antiReplay.nonce, pValidationData->rgbExternalData, + sizeof(antiReplay.nonce)); + } + + if ((result = RPC_CreateRevocableEndorsementKeyPair(tspContext, antiReplay, ekSize, ek, + genResetAuth, &eKResetAuth, &newEKSize, + &newEK, &digest))) + return result; + + if (pValidationData == NULL) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_HashUpdate(&hashCtx, newEKSize, newEK); + result |= Trspi_HashUpdate(&hashCtx, TPM_SHA1_160_HASH_LEN, antiReplay.nonce); + if ((result |= Trspi_HashFinal(&hashCtx, hash.digest))) + goto done; + + if (memcmp(hash.digest, digest.digest, TPM_SHA1_160_HASH_LEN)) { + LogError("Internal verification failed"); + result = TSPERR(TSS_E_EK_CHECKSUM); + goto done; + } + } else { + pValidationData->rgbData = calloc_tspi(tspContext, newEKSize); + if (pValidationData->rgbData == NULL) { + LogError("malloc of %u bytes failed.", newEKSize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + pValidationData->ulDataLength = newEKSize; + memcpy(pValidationData->rgbData, newEK, newEKSize); + memcpy(&pValidationData->rgbData[ekSize], antiReplay.nonce, + sizeof(antiReplay.nonce)); + + pValidationData->rgbValidationData = calloc_tspi(tspContext, + TPM_SHA1_160_HASH_LEN); + if (pValidationData->rgbValidationData == NULL) { + LogError("malloc of %d bytes failed.", TPM_SHA1_160_HASH_LEN); + free_tspi(tspContext, pValidationData->rgbData); + pValidationData->rgbData = NULL; + pValidationData->ulDataLength = 0; + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + pValidationData->ulValidationDataLength = TPM_SHA1_160_HASH_LEN; + memcpy(pValidationData->rgbValidationData, digest.digest, TPM_SHA1_160_HASH_LEN); + } + + if ((result = obj_rsakey_set_pubkey(hKey, FALSE, newEK))) { + if (pValidationData) { + free_tspi(tspContext, pValidationData->rgbValidationData); + free_tspi(tspContext, pValidationData->rgbData); + pValidationData->rgbData = NULL; + pValidationData->ulDataLength = 0; + pValidationData->rgbValidationData = NULL; + pValidationData->ulValidationDataLength = 0; + } + goto done; + } + + if (genResetAuth) { + if ((*prgbEkResetData = calloc_tspi(tspContext, sizeof(eKResetAuth.digest))) == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(eKResetAuth.digest)); + if (pValidationData) { + free_tspi(tspContext, pValidationData->rgbValidationData); + free_tspi(tspContext, pValidationData->rgbData); + pValidationData->rgbData = NULL; + pValidationData->ulDataLength = 0; + pValidationData->rgbValidationData = NULL; + pValidationData->ulValidationDataLength = 0; + } + goto done; + } + + memcpy(*prgbEkResetData, eKResetAuth.digest, sizeof(eKResetAuth.digest)); + *pulEkResetDataLength = sizeof(eKResetAuth.digest); + } + +done: + free(newEK); + + return result; +} + +TSS_RESULT +Tspi_TPM_RevokeEndorsementKey(TSS_HTPM hTPM, /* in */ + UINT32 ulEkResetDataLength, /* in */ + BYTE * rgbEkResetData) /* in */ +{ + TSS_HCONTEXT tspContext; + TPM_DIGEST eKResetAuth; + TSS_RESULT result; + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if (ulEkResetDataLength < sizeof(eKResetAuth.digest) || !rgbEkResetData) + return TSPERR(TSS_E_BAD_PARAMETER); + + memcpy(eKResetAuth.digest, rgbEkResetData, sizeof(eKResetAuth.digest)); + + if ((result = RPC_RevokeEndorsementKeyPair(tspContext, &eKResetAuth))) + return result; + + return result; +} +#endif + diff --git a/src/tspi/tspi_getset.c b/src/tspi/tspi_getset.c new file mode 100644 index 0000000..3fa8727 --- /dev/null +++ b/src/tspi/tspi_getset.c @@ -0,0 +1,1168 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <errno.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" +#include "tsp_audit.h" + + +TSS_RESULT +Tspi_SetAttribUint32(TSS_HOBJECT hObject, /* in */ + TSS_FLAG attribFlag, /* in */ + TSS_FLAG subFlag, /* in */ + UINT32 ulAttrib) /* in */ +{ + TSS_RESULT result; + + if (obj_is_rsakey(hObject)) { +#ifdef TSS_BUILD_RSAKEY_LIST + if (attribFlag == TSS_TSPATTRIB_KEY_REGISTER) { + if (subFlag) + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + + if (ulAttrib == TSS_TSPATTRIB_KEYREGISTER_USER) + result = obj_rsakey_set_pstype(hObject, TSS_PS_TYPE_USER); + else if (ulAttrib == TSS_TSPATTRIB_KEYREGISTER_SYSTEM) + result = obj_rsakey_set_pstype(hObject, TSS_PS_TYPE_SYSTEM); + else if (ulAttrib == TSS_TSPATTRIB_KEYREGISTER_NO) + result = obj_rsakey_set_pstype(hObject, TSS_PS_TYPE_NO); + else + return TSPERR(TSS_E_INVALID_ATTRIB_DATA); + } else if (attribFlag == TSS_TSPATTRIB_KEY_INFO) { + switch (subFlag) { + case TSS_TSPATTRIB_KEYINFO_USAGE: + result = obj_rsakey_set_usage(hObject, ulAttrib); + break; + case TSS_TSPATTRIB_KEYINFO_MIGRATABLE: + if (ulAttrib != TRUE && ulAttrib != FALSE) + return TSPERR(TSS_E_INVALID_ATTRIB_DATA); + + result = obj_rsakey_set_migratable(hObject, ulAttrib); + break; + case TSS_TSPATTRIB_KEYINFO_REDIRECTED: + if (ulAttrib != TRUE && ulAttrib != FALSE) + return TSPERR(TSS_E_INVALID_ATTRIB_DATA); + + result = obj_rsakey_set_redirected(hObject, ulAttrib); + break; + case TSS_TSPATTRIB_KEYINFO_VOLATILE: + if (ulAttrib != TRUE && ulAttrib != FALSE) + return TSPERR(TSS_E_INVALID_ATTRIB_DATA); + + result = obj_rsakey_set_volatile(hObject, ulAttrib); + break; + case TSS_TSPATTRIB_KEYINFO_AUTHUSAGE: + /* fall through */ + case TSS_TSPATTRIB_KEYINFO_AUTHDATAUSAGE: + if (ulAttrib != TRUE && ulAttrib != FALSE) + return TSPERR(TSS_E_INVALID_ATTRIB_DATA); + + result = obj_rsakey_set_authdata_usage(hObject, ulAttrib); + break; + case TSS_TSPATTRIB_KEYINFO_ALGORITHM: + result = obj_rsakey_set_alg(hObject, ulAttrib); + break; + case TSS_TSPATTRIB_KEYINFO_ENCSCHEME: + if (ulAttrib != TSS_ES_NONE && + ulAttrib != TSS_ES_RSAESPKCSV15 && + ulAttrib != TSS_ES_RSAESOAEP_SHA1_MGF1) + return TSPERR(TSS_E_INVALID_ATTRIB_DATA); + + result = obj_rsakey_set_es(hObject, ulAttrib); + break; + case TSS_TSPATTRIB_KEYINFO_SIGSCHEME: + if (ulAttrib != TSS_SS_NONE && + ulAttrib != TSS_SS_RSASSAPKCS1V15_SHA1 && + ulAttrib != TSS_SS_RSASSAPKCS1V15_DER && + ulAttrib != TSS_SS_RSASSAPKCS1V15_INFO) + return TSPERR(TSS_E_INVALID_ATTRIB_DATA); + + result = obj_rsakey_set_ss(hObject, ulAttrib); + break; + case TSS_TSPATTRIB_KEYINFO_KEYFLAGS: + result = obj_rsakey_set_flags(hObject, ulAttrib); + break; + case TSS_TSPATTRIB_KEYINFO_SIZE: + result = obj_rsakey_set_size(hObject, ulAttrib); + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + } else if (attribFlag == TSS_TSPATTRIB_RSAKEY_INFO) { + if (subFlag == TSS_TSPATTRIB_KEYINFO_RSA_PRIMES) { + result = obj_rsakey_set_num_primes(hObject, ulAttrib); + } else + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } else + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); +#endif +#ifdef TSS_BUILD_NV + } else if (obj_is_nvstore(hObject)) { + switch (attribFlag) { + case TSS_TSPATTRIB_NV_INDEX: + if ((result = obj_nvstore_set_index(hObject, ulAttrib))) + return result; + break; + case TSS_TSPATTRIB_NV_DATASIZE: + if ((result = obj_nvstore_set_datasize(hObject, ulAttrib))) + return result; + break; + case TSS_TSPATTRIB_NV_PERMISSIONS: + if ((result = obj_nvstore_set_permission(hObject, ulAttrib))) + return result; + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } +#endif + } else if (obj_is_policy(hObject)) { + switch (attribFlag) { + case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC: + case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC: + case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP: + case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM: + result = obj_policy_set_cb11(hObject, attribFlag, + subFlag, ulAttrib); + break; + case TSS_TSPATTRIB_POLICY_SECRET_LIFETIME: + if (subFlag == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS || + subFlag == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER || + subFlag == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER) { + result = obj_policy_set_lifetime(hObject, subFlag, + ulAttrib); + } else { + result = TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; + case TSS_TSPATTRIB_SECRET_HASH_MODE: + result = obj_policy_set_hash_mode(hObject, ulAttrib); + break; +#ifdef TSS_BUILD_DELEGATION + case TSS_TSPATTRIB_POLICY_DELEGATION_INFO: + switch (subFlag) { + case TSS_TSPATTRIB_POLDEL_TYPE: + switch (ulAttrib) { + case TSS_DELEGATIONTYPE_NONE: + case TSS_DELEGATIONTYPE_OWNER: + case TSS_DELEGATIONTYPE_KEY: + result = obj_policy_set_delegation_type(hObject, + ulAttrib); + break; + default: + result = TSPERR(TSS_E_INVALID_ATTRIB_DATA); + } + break; + case TSS_TSPATTRIB_POLDEL_INDEX: + result = obj_policy_set_delegation_index(hObject, ulAttrib); + break; + case TSS_TSPATTRIB_POLDEL_PER1: + result = obj_policy_set_delegation_per1(hObject, ulAttrib); + break; + case TSS_TSPATTRIB_POLDEL_PER2: + result = obj_policy_set_delegation_per2(hObject, ulAttrib); + break; + default: + result = TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; +#endif + default: + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } + } else if (obj_is_context(hObject)) { + switch (attribFlag) { + case TSS_TSPATTRIB_CONTEXT_SILENT_MODE: + if (ulAttrib == TSS_TSPATTRIB_CONTEXT_NOT_SILENT) + result = obj_context_set_mode(hObject, ulAttrib); + else if (ulAttrib == TSS_TSPATTRIB_CONTEXT_SILENT) { + if (obj_context_has_popups(hObject)) + return TSPERR(TSS_E_SILENT_CONTEXT); + result = obj_context_set_mode(hObject, ulAttrib); + } else + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + break; +#ifdef TSS_BUILD_TRANSPORT + case TSS_TSPATTRIB_CONTEXT_TRANSPORT: + if (subFlag == TSS_TSPATTRIB_CONTEXTTRANS_CONTROL) { + if (ulAttrib != TSS_TSPATTRIB_DISABLE_TRANSPORT && + ulAttrib != TSS_TSPATTRIB_ENABLE_TRANSPORT) + return TSPERR(TSS_E_INVALID_ATTRIB_DATA); + + result = obj_context_transport_set_control(hObject, + ulAttrib); + } else if (subFlag == TSS_TSPATTRIB_CONTEXTTRANS_MODE) { + switch (ulAttrib) { + case TSS_TSPATTRIB_TRANSPORT_NO_DEFAULT_ENCRYPTION: + case TSS_TSPATTRIB_TRANSPORT_DEFAULT_ENCRYPTION: + case TSS_TSPATTRIB_TRANSPORT_AUTHENTIC_CHANNEL: + case TSS_TSPATTRIB_TRANSPORT_EXCLUSIVE: + case TSS_TSPATTRIB_TRANSPORT_STATIC_AUTH: + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_DATA); + } + + result = obj_context_transport_set_mode(hObject, ulAttrib); + } else + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + + break; +#endif + case TSS_TSPATTRIB_SECRET_HASH_MODE: + result = obj_context_set_hash_mode(hObject, ulAttrib); + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } + } else if (obj_is_tpm(hObject)) { + switch (attribFlag) { + case TSS_TSPATTRIB_TPM_CALLBACK_COLLATEIDENTITY: + case TSS_TSPATTRIB_TPM_CALLBACK_ACTIVATEIDENTITY: + if ((result = obj_tpm_set_cb11(hObject, attribFlag, subFlag, + ulAttrib))) + return result; + break; +#ifdef TSS_BUILD_AUDIT + case TSS_TSPATTRIB_TPM_ORDINAL_AUDIT_STATUS: + result = __tspi_audit_set_ordinal_audit_status(hObject, attribFlag, + subFlag, ulAttrib); + break; +#endif + default: + result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } +#ifdef TSS_BUILD_SEALX + } else if (obj_is_encdata(hObject)) { + if (attribFlag != TSS_TSPATTRIB_ENCDATA_SEAL) + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + if (subFlag == TSS_TSPATTRIB_ENCDATASEAL_PROTECT_MODE) { + if (ulAttrib != TSS_TSPATTRIB_ENCDATASEAL_NO_PROTECT && + ulAttrib != TSS_TSPATTRIB_ENCDATASEAL_PROTECT) + return TSPERR(TSS_E_INVALID_ATTRIB_DATA); + + result = obj_encdata_set_seal_protect_mode(hObject, ulAttrib); + } else + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); +#endif +#ifdef TSS_BUILD_DELEGATION + } else if (obj_is_delfamily(hObject)) { + switch (attribFlag) { + case TSS_TSPATTRIB_DELFAMILY_STATE: + switch (subFlag) { + case TSS_TSPATTRIB_DELFAMILYSTATE_LOCKED: + result = obj_delfamily_set_locked(hObject, (TSS_BOOL)ulAttrib, TRUE); + break; + case TSS_TSPATTRIB_DELFAMILYSTATE_ENABLED: + result = obj_delfamily_set_enabled(hObject, (TSS_BOOL)ulAttrib, TRUE); + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + } +#endif + } else { + if (obj_is_hash(hObject) || obj_is_pcrs(hObject)) + result = TSPERR(TSS_E_BAD_PARAMETER); + else + result = TSPERR(TSS_E_INVALID_HANDLE); + } + + return result; +} + +TSS_RESULT +Tspi_GetAttribUint32(TSS_HOBJECT hObject, /* in */ + TSS_FLAG attribFlag, /* in */ + TSS_FLAG subFlag, /* in */ + UINT32 * pulAttrib) /* out */ +{ + UINT32 attrib; + TSS_RESULT result = TSS_SUCCESS; + + if (pulAttrib == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (obj_is_rsakey(hObject)) { +#ifdef TSS_BUILD_RSAKEY_LIST + if (attribFlag == TSS_TSPATTRIB_KEY_REGISTER) { + if (subFlag != 0) + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + + if ((result = obj_rsakey_get_pstype(hObject, &attrib))) + return result; + + if (attrib == TSS_PS_TYPE_USER) + *pulAttrib = TSS_TSPATTRIB_KEYREGISTER_USER; + else if (attrib == TSS_PS_TYPE_SYSTEM) + *pulAttrib = TSS_TSPATTRIB_KEYREGISTER_SYSTEM; + else + *pulAttrib = TSS_TSPATTRIB_KEYREGISTER_NO; + } else if (attribFlag == TSS_TSPATTRIB_KEY_INFO) { + switch (subFlag) { + case TSS_TSPATTRIB_KEYINFO_USAGE: + if ((result = obj_rsakey_get_usage(hObject, pulAttrib))) + return result; + break; + case TSS_TSPATTRIB_KEYINFO_MIGRATABLE: + *pulAttrib = obj_rsakey_is_migratable(hObject); + break; + case TSS_TSPATTRIB_KEYINFO_REDIRECTED: + *pulAttrib = obj_rsakey_is_redirected(hObject); + break; + case TSS_TSPATTRIB_KEYINFO_VOLATILE: + *pulAttrib = obj_rsakey_is_volatile(hObject); + break; + case TSS_TSPATTRIB_KEYINFO_AUTHUSAGE: + /* fall through */ + case TSS_TSPATTRIB_KEYINFO_AUTHDATAUSAGE: + if ((result = obj_rsakey_get_authdata_usage(hObject, pulAttrib))) + return result; + break; + case TSS_TSPATTRIB_KEYINFO_ALGORITHM: + if ((result = obj_rsakey_get_alg(hObject, pulAttrib))) + return result; + break; + case TSS_TSPATTRIB_KEYINFO_ENCSCHEME: + if ((result = obj_rsakey_get_es(hObject, pulAttrib))) + return result; + break; + case TSS_TSPATTRIB_KEYINFO_SIGSCHEME: + if ((result = obj_rsakey_get_ss(hObject, pulAttrib))) + return result; + break; + case TSS_TSPATTRIB_KEYINFO_KEYFLAGS: + if ((result = obj_rsakey_get_flags(hObject, pulAttrib))) + return result; + break; + case TSS_TSPATTRIB_KEYINFO_SIZE: + if ((result = obj_rsakey_get_size(hObject, pulAttrib))) + return result; + break; +#ifdef TSS_BUILD_CMK + case TSS_TSPATTRIB_KEYINFO_CMK: + *pulAttrib = obj_rsakey_is_cmk(hObject); + break; +#endif + default: + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + } else if (attribFlag == TSS_TSPATTRIB_RSAKEY_INFO) { + if (subFlag == TSS_TSPATTRIB_KEYINFO_RSA_KEYSIZE) { + if ((result = obj_rsakey_get_size(hObject, pulAttrib))) + return result; + } else if (subFlag == TSS_TSPATTRIB_KEYINFO_RSA_PRIMES) { + if ((result = obj_rsakey_get_num_primes(hObject, pulAttrib))) + return result; + } else { + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + } else if (attribFlag == TSS_TSPATTRIB_KEY_PCR_LONG) { + if (subFlag == TSS_TSPATTRIB_KEYPCRLONG_LOCALITY_ATCREATION || + subFlag == TSS_TSPATTRIB_KEYPCRLONG_LOCALITY_ATRELEASE) { + result = obj_rsakey_get_pcr_locality(hObject, subFlag, pulAttrib); + } else + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } else + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); +#endif +#ifdef TSS_BUILD_NV + } else if (obj_is_nvstore(hObject)) { + switch (attribFlag) { + case TSS_TSPATTRIB_NV_INDEX: + if ((result = obj_nvstore_get_index(hObject, pulAttrib))) + return result; + break; + case TSS_TSPATTRIB_NV_DATASIZE: + if ((result = obj_nvstore_get_datasize(hObject, pulAttrib))) + return result; + break; + case TSS_TSPATTRIB_NV_PERMISSIONS: + if ((result = obj_nvstore_get_permission(hObject, pulAttrib))) + return result; + break; + case TSS_TSPATTRIB_NV_STATE: + switch (subFlag) { + case TSS_TSPATTRIB_NVSTATE_READSTCLEAR: + if ((result = + obj_nvstore_get_state_readstclear(hObject, + pulAttrib))) + return result; + break; + case TSS_TSPATTRIB_NVSTATE_WRITEDEFINE: + if ((result = + obj_nvstore_get_state_writedefine(hObject, + pulAttrib))) + return result; + break; + case TSS_TSPATTRIB_NVSTATE_WRITESTCLEAR: + if ((result = + obj_nvstore_get_state_writestclear(hObject, + pulAttrib))) + return result; + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; + case TSS_TSPATTRIB_NV_PCR: + switch (subFlag) { + case TSS_TSPATTRIB_NVPCR_READLOCALITYATRELEASE: + if ((result = + obj_nvstore_get_readlocalityatrelease(hObject, + pulAttrib))) + return result; + break; + case TSS_TSPATTRIB_NVPCR_WRITELOCALITYATRELEASE: + if ((result = + obj_nvstore_get_writelocalityatrelease(hObject, + pulAttrib))) + return result; + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; + case TSS_TSPATTRIB_KEYCONTROL_OWNEREVICT: + if ((result = obj_rsakey_get_ownerevict(hObject, pulAttrib))) + return result; + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + } +#endif + } else if (obj_is_policy(hObject)) { + switch (attribFlag) { + case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC: + case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC: + case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP: + case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM: + if ((result = obj_policy_get_cb11(hObject, attribFlag, pulAttrib))) + return result; + break; + case TSS_TSPATTRIB_POLICY_SECRET_LIFETIME: + if ((result = obj_policy_get_lifetime(hObject, &attrib))) + return result; + + if (subFlag == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS) { + if (attrib == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS) + *pulAttrib = TRUE; + else + *pulAttrib = FALSE; + } else if (subFlag == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER) { + if (attrib != TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER) + return TSPERR(TSS_E_BAD_PARAMETER); + if ((result = obj_policy_get_counter(hObject, pulAttrib))) + return result; + } else if (subFlag == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER) { + if ((result = + obj_policy_get_secs_until_expired(hObject, pulAttrib))) + return result; + } else + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + break; + case TSS_TSPATTRIB_SECRET_HASH_MODE: + if (subFlag == TSS_TSPATTRIB_SECRET_HASH_MODE_POPUP) + result = obj_policy_get_hash_mode(hObject, pulAttrib); + else + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + break; +#ifdef TSS_BUILD_DELEGATION + case TSS_TSPATTRIB_POLICY_DELEGATION_INFO: + switch (subFlag) { + case TSS_TSPATTRIB_POLDEL_TYPE: + result = obj_policy_get_delegation_type(hObject, + pulAttrib); + break; + case TSS_TSPATTRIB_POLDEL_INDEX: + result = obj_policy_get_delegation_index(hObject, + pulAttrib); + break; + case TSS_TSPATTRIB_POLDEL_PER1: + result = obj_policy_get_delegation_per1(hObject, + pulAttrib); + break; + case TSS_TSPATTRIB_POLDEL_PER2: + result = obj_policy_get_delegation_per2(hObject, + pulAttrib); + break; + case TSS_TSPATTRIB_POLDEL_LABEL: + result = obj_policy_get_delegation_label(hObject, + (BYTE *)pulAttrib); + break; + case TSS_TSPATTRIB_POLDEL_FAMILYID: + result = obj_policy_get_delegation_familyid(hObject, + pulAttrib); + break; + case TSS_TSPATTRIB_POLDEL_VERCOUNT: + result = obj_policy_get_delegation_vercount(hObject, + pulAttrib); + break; + default: + result = TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; + case TSS_TSPATTRIB_POLICY_DELEGATION_PCR: + switch (subFlag) { + case TSS_TSPATTRIB_POLDELPCR_LOCALITY: + result = obj_policy_get_delegation_pcr_locality(hObject, + pulAttrib); + break; + default: + result = TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; +#endif + default: + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } + } else if (obj_is_context(hObject)) { + switch (attribFlag) { + case TSS_TSPATTRIB_CONTEXT_SILENT_MODE: + if ((result = obj_context_get_mode(hObject, pulAttrib))) + return result; + break; + case TSS_TSPATTRIB_SECRET_HASH_MODE: + if (subFlag == TSS_TSPATTRIB_SECRET_HASH_MODE_POPUP) + result = obj_context_get_hash_mode(hObject, pulAttrib); + else + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + break; +#ifdef TSS_BUILD_TRANSPORT + case TSS_TSPATTRIB_CONTEXT_TRANSPORT: + if (subFlag == TSS_TSPATTRIB_DISABLE_TRANSPORT || + subFlag == TSS_TSPATTRIB_ENABLE_TRANSPORT) { + result = obj_context_transport_get_control(hObject, subFlag, + pulAttrib); + } else if ( + subFlag == TSS_TSPATTRIB_TRANSPORT_NO_DEFAULT_ENCRYPTION || + subFlag == TSS_TSPATTRIB_TRANSPORT_DEFAULT_ENCRYPTION || + subFlag == TSS_TSPATTRIB_TRANSPORT_AUTHENTIC_CHANNEL || + subFlag == TSS_TSPATTRIB_TRANSPORT_EXCLUSIVE || + subFlag == TSS_TSPATTRIB_TRANSPORT_STATIC_AUTH) { + result = obj_context_transport_get_mode(hObject, subFlag, + pulAttrib); + } else + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + break; +#endif + default: + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } + } else if (obj_is_tpm(hObject)) { + switch (attribFlag) { + case TSS_TSPATTRIB_TPM_CALLBACK_COLLATEIDENTITY: + case TSS_TSPATTRIB_TPM_CALLBACK_ACTIVATEIDENTITY: + if ((result = obj_tpm_get_cb11(hObject, attribFlag, pulAttrib))) + return result; + break; + default: + result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } + } else if (obj_is_encdata(hObject)) { +#ifdef TSS_BUILD_SEALX + if (attribFlag == TSS_TSPATTRIB_ENCDATA_SEAL) { + if (subFlag == TSS_TSPATTRIB_ENCDATASEAL_PROTECT_MODE) + result = obj_encdata_get_seal_protect_mode(hObject, pulAttrib); + else + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } else if (attribFlag == TSS_TSPATTRIB_ENCDATA_PCR_LONG) { + if (subFlag == TSS_TSPATTRIB_ENCDATAPCRLONG_LOCALITY_ATCREATION || + subFlag == TSS_TSPATTRIB_ENCDATAPCRLONG_LOCALITY_ATRELEASE) { + result = obj_encdata_get_pcr_locality(hObject, subFlag, pulAttrib); + } else + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } else + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); +#endif +#ifdef TSS_BUILD_DELEGATION + } else if (obj_is_delfamily(hObject)) { + switch (attribFlag) { + case TSS_TSPATTRIB_DELFAMILY_STATE: + switch (subFlag) { + case TSS_TSPATTRIB_DELFAMILYSTATE_LOCKED: + result = obj_delfamily_get_locked(hObject, (TSS_BOOL *)pulAttrib); + break; + case TSS_TSPATTRIB_DELFAMILYSTATE_ENABLED: + result = obj_delfamily_get_enabled(hObject, (TSS_BOOL *)pulAttrib); + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; + case TSS_TSPATTRIB_DELFAMILY_INFO: + switch (subFlag) { + case TSS_TSPATTRIB_DELFAMILYINFO_LABEL: + result = obj_delfamily_get_label(hObject, (BYTE *)pulAttrib); + break; + case TSS_TSPATTRIB_DELFAMILYINFO_VERCOUNT: + result = obj_delfamily_get_vercount(hObject, pulAttrib); + break; + case TSS_TSPATTRIB_DELFAMILYINFO_FAMILYID: + result = obj_delfamily_get_familyid(hObject, pulAttrib); + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + } +#endif + } else { + if (obj_is_hash(hObject) || obj_is_pcrs(hObject)) + result = TSPERR(TSS_E_BAD_PARAMETER); + else + result = TSPERR(TSS_E_INVALID_HANDLE); + } + + return result; +} + +TSS_RESULT +Tspi_SetAttribData(TSS_HOBJECT hObject, /* in */ + TSS_FLAG attribFlag, /* in */ + TSS_FLAG subFlag, /* in */ + UINT32 ulAttribDataSize, /* in */ + BYTE * rgbAttribData) /* in */ +{ + TSS_RESULT result; + BYTE *string = NULL; + + if (obj_is_rsakey(hObject)) { +#ifdef TSS_BUILD_RSAKEY_LIST + if (attribFlag == TSS_TSPATTRIB_KEY_BLOB) { + if (subFlag == TSS_TSPATTRIB_KEYBLOB_BLOB) { + /* A TPM_KEY(12) structure, in blob form */ + result = obj_rsakey_set_tcpakey(hObject, ulAttribDataSize, + rgbAttribData); + if (result == TSS_SUCCESS) + result = obj_rsakey_set_tcs_handle(hObject, 0); + } else if (subFlag == TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY) { + /* A TCPA_PUBKEY structure, in blob form */ + result = obj_rsakey_set_pubkey(hObject, FALSE, rgbAttribData); + } else if (subFlag == TSS_TSPATTRIB_KEYBLOB_PRIVATE_KEY) { + /* A blob, either encrypted or unencrypted */ + result = obj_rsakey_set_privkey(hObject, FALSE, ulAttribDataSize, + rgbAttribData); + } else { + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + } else if (attribFlag == TSS_TSPATTRIB_RSAKEY_INFO) { + if (subFlag == TSS_TSPATTRIB_KEYINFO_RSA_EXPONENT) { + result = obj_rsakey_set_exponent(hObject, ulAttribDataSize, + rgbAttribData); + } else if (subFlag == TSS_TSPATTRIB_KEYINFO_RSA_MODULUS) { + result = obj_rsakey_set_modulus(hObject, ulAttribDataSize, + rgbAttribData); + } else { + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } +#ifdef TSS_BUILD_CMK + } else if (attribFlag == TSS_TSPATTRIB_KEY_CMKINFO) { + if (subFlag == TSS_TSPATTRIB_KEYINFO_CMK_MA_APPROVAL) { + result = obj_rsakey_set_msa_approval(hObject, ulAttribDataSize, + rgbAttribData); + } else if (subFlag == TSS_TSPATTRIB_KEYINFO_CMK_MA_DIGEST) { + result = obj_rsakey_set_msa_digest(hObject, ulAttribDataSize, + rgbAttribData); + } else { + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } +#endif + } else { + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + } +#endif + } else if (obj_is_encdata(hObject)) { +#ifdef TSS_BUILD_ENCDATA_LIST + if (attribFlag != TSS_TSPATTRIB_ENCDATA_BLOB) + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + if (subFlag != TSS_TSPATTRIB_ENCDATABLOB_BLOB) + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + + result = obj_encdata_set_data(hObject, ulAttribDataSize, rgbAttribData); +#endif + } else if (obj_is_policy(hObject)) { + switch (attribFlag) { + case TSS_TSPATTRIB_POLICY_POPUPSTRING: + if ((string = Trspi_UNICODE_To_Native(rgbAttribData, + NULL)) == NULL) + return TSPERR(TSS_E_INTERNAL_ERROR); + + result = obj_policy_set_string(hObject, + ulAttribDataSize, + string); + break; + case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC: + case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC: + case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP: + case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM: +#ifdef TSS_BUILD_SEALX + case TSS_TSPATTRIB_POLICY_CALLBACK_SEALX_MASK: +#endif + result = obj_policy_set_cb12(hObject, attribFlag, + rgbAttribData); + break; +#ifdef TSS_BUILD_DELEGATION + case TSS_TSPATTRIB_POLICY_DELEGATION_INFO: + switch (subFlag) { + case TSS_TSPATTRIB_POLDEL_OWNERBLOB: + result = obj_policy_set_delegation_blob(hObject, + TSS_DELEGATIONTYPE_OWNER, + ulAttribDataSize, rgbAttribData); + break; + case TSS_TSPATTRIB_POLDEL_KEYBLOB: + result = obj_policy_set_delegation_blob(hObject, + TSS_DELEGATIONTYPE_KEY, + ulAttribDataSize, rgbAttribData); + break; + default: + result = TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; +#endif + default: + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } + } else if (obj_is_hash(hObject)) { +#ifdef TSS_BUILD_HASH_LIST + if (attribFlag != TSS_TSPATTRIB_HASH_IDENTIFIER) + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + + if (subFlag != 0) + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + + result = obj_hash_set_value(hObject, ulAttribDataSize, rgbAttribData); +#endif + } else if (obj_is_tpm(hObject)) { + switch (attribFlag) { + case TSS_TSPATTRIB_TPM_CALLBACK_COLLATEIDENTITY: + case TSS_TSPATTRIB_TPM_CALLBACK_ACTIVATEIDENTITY: + result = obj_tpm_set_cb12(hObject, attribFlag, + rgbAttribData); + break; + case TSS_TSPATTRIB_TPM_CREDENTIAL: + if (subFlag == TSS_TPMATTRIB_EKCERT || + subFlag == TSS_TPMATTRIB_TPM_CC || + subFlag == TSS_TPMATTRIB_PLATFORMCERT || + subFlag == TSS_TPMATTRIB_PLATFORM_CC) { + result = obj_tpm_set_cred(hObject, subFlag, + ulAttribDataSize, rgbAttribData); + } else { + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } + } else if (obj_is_migdata(hObject)) { +#ifdef TSS_BUILD_CMK + switch (attribFlag) { + case TSS_MIGATTRIB_MIGRATIONBLOB: + switch (subFlag) { + case TSS_MIGATTRIB_MIG_MSALIST_PUBKEY_BLOB: + case TSS_MIGATTRIB_MIG_AUTHORITY_PUBKEY_BLOB: + case TSS_MIGATTRIB_MIG_DESTINATION_PUBKEY_BLOB: + case TSS_MIGATTRIB_MIG_SOURCE_PUBKEY_BLOB: + result = obj_migdata_set_migrationblob(hObject, subFlag, + ulAttribDataSize, rgbAttribData); + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; + case TSS_MIGATTRIB_MIGRATIONTICKET: + if (subFlag != 0) + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + result = obj_migdata_set_ticket_blob(hObject, ulAttribDataSize, rgbAttribData); + break; + case TSS_MIGATTRIB_AUTHORITY_DATA: + switch (subFlag) { + case TSS_MIGATTRIB_AUTHORITY_DIGEST: + case TSS_MIGATTRIB_AUTHORITY_APPROVAL_HMAC: + case TSS_MIGATTRIB_AUTHORITY_MSALIST: + result = obj_migdata_set_authoritydata(hObject, subFlag, + ulAttribDataSize, rgbAttribData); + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; + case TSS_MIGATTRIB_MIG_AUTH_DATA: + switch (subFlag) { + case TSS_MIGATTRIB_MIG_AUTH_AUTHORITY_DIGEST: + case TSS_MIGATTRIB_MIG_AUTH_DESTINATION_DIGEST: + case TSS_MIGATTRIB_MIG_AUTH_SOURCE_DIGEST: + result = obj_migdata_set_migauthdata(hObject, subFlag, + ulAttribDataSize, rgbAttribData); + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; + case TSS_MIGATTRIB_TICKET_DATA: + switch (subFlag) { + case TSS_MIGATTRIB_TICKET_SIG_DIGEST: + case TSS_MIGATTRIB_TICKET_SIG_VALUE: + case TSS_MIGATTRIB_TICKET_SIG_TICKET: + case TSS_MIGATTRIB_TICKET_RESTRICT_TICKET: + result = obj_migdata_set_ticketdata(hObject, subFlag, + ulAttribDataSize, rgbAttribData); + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } +#endif + } else { + if (obj_is_pcrs(hObject) || obj_is_context(hObject)) + result = TSPERR(TSS_E_BAD_PARAMETER); +#ifdef TSS_BUILD_NV + else if (obj_is_nvstore(hObject)) + result = TSPERR(TSS_E_BAD_PARAMETER); +#endif + else + result = TSPERR(TSS_E_INVALID_HANDLE); + } + + return result; +} + +TSS_RESULT +Tspi_GetAttribData(TSS_HOBJECT hObject, /* in */ + TSS_FLAG attribFlag, /* in */ + TSS_FLAG subFlag, /* in */ + UINT32 * pulAttribDataSize, /* out */ + BYTE ** prgbAttribData) /* out */ +{ + TSS_RESULT result; + + if (pulAttribDataSize == NULL || prgbAttribData == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (obj_is_rsakey(hObject)) { +#ifdef TSS_BUILD_RSAKEY_LIST + if (attribFlag == TSS_TSPATTRIB_KEY_BLOB) { + if (subFlag == TSS_TSPATTRIB_KEYBLOB_BLOB) { + /* A TPM_KEY(12) structure, in blob form */ + result = obj_rsakey_get_blob(hObject, pulAttribDataSize, + prgbAttribData); + } else if (subFlag == TSS_TSPATTRIB_KEYBLOB_PRIVATE_KEY) { + /* A blob, either encrypted or unencrypted */ + result = obj_rsakey_get_priv_blob(hObject, pulAttribDataSize, + prgbAttribData); + } else if (subFlag == TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY) { + /* A TCPA_PUBKEY structure, in blob form */ + result = obj_rsakey_get_pub_blob(hObject, pulAttribDataSize, + prgbAttribData); + } else { + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + } else if (attribFlag == TSS_TSPATTRIB_KEY_INFO) { + if (subFlag != TSS_TSPATTRIB_KEYINFO_VERSION) + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + + result = obj_rsakey_get_version(hObject, pulAttribDataSize, + prgbAttribData); + } else if (attribFlag == TSS_TSPATTRIB_RSAKEY_INFO) { + if (subFlag == TSS_TSPATTRIB_KEYINFO_RSA_EXPONENT) { + result = obj_rsakey_get_exponent(hObject, pulAttribDataSize, + prgbAttribData); + } else if (subFlag == TSS_TSPATTRIB_KEYINFO_RSA_MODULUS) { + result = obj_rsakey_get_modulus(hObject, pulAttribDataSize, + prgbAttribData); + } else + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } else if (attribFlag == TSS_TSPATTRIB_KEY_UUID) { + if (subFlag) + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + + result = obj_rsakey_get_uuid(hObject, pulAttribDataSize, prgbAttribData); + } else if (attribFlag == TSS_TSPATTRIB_KEY_PCR) { + if (subFlag == TSS_TSPATTRIB_KEYPCR_DIGEST_ATCREATION || + subFlag == TSS_TSPATTRIB_KEYPCR_DIGEST_ATRELEASE) { + result = obj_rsakey_get_pcr_digest(hObject, TSS_PCRS_STRUCT_INFO, + subFlag, pulAttribDataSize, + prgbAttribData); + } else if (subFlag == TSS_TSPATTRIB_KEYPCR_SELECTION) { + result = obj_rsakey_get_pcr_selection(hObject, TSS_PCRS_STRUCT_INFO, + subFlag, pulAttribDataSize, + prgbAttribData); + } else + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } else if (attribFlag == TSS_TSPATTRIB_KEY_PCR_LONG) { + if (subFlag == TSS_TSPATTRIB_KEYPCRLONG_DIGEST_ATCREATION || + subFlag == TSS_TSPATTRIB_KEYPCRLONG_DIGEST_ATRELEASE) { + result = obj_rsakey_get_pcr_digest(hObject, + TSS_PCRS_STRUCT_INFO_LONG, + subFlag, pulAttribDataSize, + prgbAttribData); + } else if (subFlag == TSS_TSPATTRIB_KEYPCRLONG_CREATION_SELECTION || + subFlag == TSS_TSPATTRIB_KEYPCRLONG_RELEASE_SELECTION) { + result = obj_rsakey_get_pcr_selection(hObject, + TSS_PCRS_STRUCT_INFO_LONG, + subFlag, pulAttribDataSize, + prgbAttribData); + } else + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); +#ifdef TSS_BUILD_CMK + } else if (attribFlag == TSS_TSPATTRIB_KEY_CMKINFO) { + if (subFlag == TSS_TSPATTRIB_KEYINFO_CMK_MA_APPROVAL) { + result = obj_rsakey_get_msa_approval(hObject, pulAttribDataSize, + prgbAttribData); + } else if (subFlag == TSS_TSPATTRIB_KEYINFO_CMK_MA_DIGEST) { + result = obj_rsakey_get_msa_digest(hObject, pulAttribDataSize, + prgbAttribData); + } else { + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } +#endif + } else + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); +#endif +#ifdef TSS_BUILD_NV + } else if (obj_is_nvstore(hObject)) { + if (attribFlag == TSS_TSPATTRIB_NV_PCR) { + switch (subFlag) { + case TSS_TSPATTRIB_NVPCR_READDIGESTATRELEASE: + if ((result = obj_nvstore_get_readdigestatrelease(hObject, + pulAttribDataSize, + prgbAttribData))) + return result; + break; + case TSS_TSPATTRIB_NVPCR_READPCRSELECTION: + if ((result = obj_nvstore_get_readpcrselection( + hObject, + pulAttribDataSize, + prgbAttribData))) + return result; + break; + case TSS_TSPATTRIB_NVPCR_WRITEDIGESTATRELEASE: + if ((result = obj_nvstore_get_writedigestatrelease(hObject, + pulAttribDataSize, + prgbAttribData))) + return result; + break; + case TSS_TSPATTRIB_NVPCR_WRITEPCRSELECTION: + if ((result = obj_nvstore_get_writepcrselection(hObject, + pulAttribDataSize, + prgbAttribData))) + return result; + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + } else + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); +#endif + } else if (obj_is_encdata(hObject)) { +#ifdef TSS_BUILD_ENCDATA_LIST + if (attribFlag == TSS_TSPATTRIB_ENCDATA_BLOB) { + if (subFlag != TSS_TSPATTRIB_ENCDATABLOB_BLOB) + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + + result = obj_encdata_get_data(hObject, pulAttribDataSize, prgbAttribData); + } else if (attribFlag == TSS_TSPATTRIB_ENCDATA_PCR) { + if (subFlag == TSS_TSPATTRIB_ENCDATAPCR_DIGEST_ATCREATION || + subFlag == TSS_TSPATTRIB_ENCDATAPCR_DIGEST_RELEASE) { + result = obj_encdata_get_pcr_digest(hObject, TSS_PCRS_STRUCT_INFO, + subFlag, pulAttribDataSize, + prgbAttribData); + } else if (subFlag == TSS_TSPATTRIB_ENCDATAPCR_SELECTION) { + result = obj_encdata_get_pcr_selection(hObject, + TSS_PCRS_STRUCT_INFO, + subFlag, pulAttribDataSize, + prgbAttribData); + } else { + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + } else if (attribFlag == TSS_TSPATTRIB_ENCDATA_PCR_LONG) { + if (subFlag == TSS_TSPATTRIB_ENCDATAPCRLONG_CREATION_SELECTION || + subFlag == TSS_TSPATTRIB_ENCDATAPCRLONG_RELEASE_SELECTION) { + result = obj_encdata_get_pcr_selection(hObject, + TSS_PCRS_STRUCT_INFO_LONG, + subFlag, pulAttribDataSize, + prgbAttribData); + } else if (subFlag == TSS_TSPATTRIB_ENCDATAPCRLONG_DIGEST_ATCREATION || + subFlag == TSS_TSPATTRIB_ENCDATAPCRLONG_DIGEST_ATRELEASE) { + result = obj_encdata_get_pcr_digest(hObject, + TSS_PCRS_STRUCT_INFO_LONG, + subFlag, pulAttribDataSize, + prgbAttribData); + } else { + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + } else { + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + } +#endif + } else if (obj_is_context(hObject)) { + if (attribFlag != TSS_TSPATTRIB_CONTEXT_MACHINE_NAME) + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + + if ((result = obj_context_get_machine_name_attrib(hObject, + pulAttribDataSize, + prgbAttribData))) + return result; + } else if (obj_is_policy(hObject)) { + switch (attribFlag) { + case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC: + case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC: + case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP: + case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM: +#ifdef TSS_BUILD_SEALX + case TSS_TSPATTRIB_POLICY_CALLBACK_SEALX_MASK: +#endif + result = obj_policy_get_cb12(hObject, attribFlag, + pulAttribDataSize, prgbAttribData); + break; + case TSS_TSPATTRIB_POLICY_POPUPSTRING: + if ((result = obj_policy_get_string(hObject, pulAttribDataSize, + prgbAttribData))) + return result; + break; +#ifdef TSS_BUILD_DELEGATION + case TSS_TSPATTRIB_POLICY_DELEGATION_INFO: + switch (subFlag) { + case TSS_TSPATTRIB_POLDEL_OWNERBLOB: + result = obj_policy_get_delegation_blob(hObject, + TSS_DELEGATIONTYPE_OWNER, + pulAttribDataSize, prgbAttribData); + break; + case TSS_TSPATTRIB_POLDEL_KEYBLOB: + result = obj_policy_get_delegation_blob(hObject, + TSS_DELEGATIONTYPE_KEY, + pulAttribDataSize, prgbAttribData); + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; + case TSS_TSPATTRIB_POLICY_DELEGATION_PCR: + switch (subFlag) { + case TSS_TSPATTRIB_POLDELPCR_DIGESTATRELEASE: + result = obj_policy_get_delegation_pcr_digest(hObject, + pulAttribDataSize, prgbAttribData); + break; + case TSS_TSPATTRIB_POLDELPCR_SELECTION: + result = obj_policy_get_delegation_pcr_selection(hObject, + pulAttribDataSize, prgbAttribData); + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; +#endif + default: + result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } + } else if (obj_is_tpm(hObject)) { + switch (attribFlag) { + case TSS_TSPATTRIB_TPM_CALLBACK_COLLATEIDENTITY: + case TSS_TSPATTRIB_TPM_CALLBACK_ACTIVATEIDENTITY: + result = obj_tpm_get_cb12(hObject, attribFlag, + pulAttribDataSize, prgbAttribData); + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } + } else if (obj_is_migdata(hObject)) { +#ifdef TSS_BUILD_CMK + switch (attribFlag) { + case TSS_MIGATTRIB_MIGRATIONBLOB: + switch (subFlag) { + case TSS_MIGATTRIB_MIG_XOR_BLOB: + result = obj_migdata_get_migrationblob(hObject, subFlag, + pulAttribDataSize, prgbAttribData); + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; + case TSS_MIGATTRIB_AUTHORITY_DATA: + switch (subFlag) { + case TSS_MIGATTRIB_AUTHORITY_DIGEST: + case TSS_MIGATTRIB_AUTHORITY_APPROVAL_HMAC: + case TSS_MIGATTRIB_AUTHORITY_MSALIST: + result = obj_migdata_get_authoritydata(hObject, subFlag, + pulAttribDataSize, prgbAttribData); + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; + case TSS_MIGATTRIB_MIG_AUTH_DATA: + switch (subFlag) { + case TSS_MIGATTRIB_MIG_AUTH_AUTHORITY_DIGEST: + case TSS_MIGATTRIB_MIG_AUTH_DESTINATION_DIGEST: + case TSS_MIGATTRIB_MIG_AUTH_SOURCE_DIGEST: + result = obj_migdata_get_migauthdata(hObject, subFlag, + pulAttribDataSize, prgbAttribData); + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; + case TSS_MIGATTRIB_TICKET_DATA: + switch (subFlag) { + case TSS_MIGATTRIB_TICKET_SIG_TICKET: + result = obj_migdata_get_ticketdata(hObject, subFlag, + pulAttribDataSize, prgbAttribData); + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG); + } + break; + default: + return TSPERR(TSS_E_INVALID_ATTRIB_FLAG); + break; + } +#endif + } else { + if (obj_is_hash(hObject) || obj_is_pcrs(hObject)) + result = TSPERR(TSS_E_BAD_PARAMETER); + else + result = TSPERR(TSS_E_INVALID_HANDLE); + } + + return result; +} + diff --git a/src/tspi/tspi_hash.c b/src/tspi/tspi_hash.c new file mode 100644 index 0000000..dfd3fcb --- /dev/null +++ b/src/tspi/tspi_hash.c @@ -0,0 +1,59 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_Hash_SetHashValue(TSS_HHASH hHash, /* in */ + UINT32 ulHashValueLength, /* in */ + BYTE * rgbHashValue) /* in */ +{ + if (ulHashValueLength == 0 || rgbHashValue == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + return obj_hash_set_value(hHash, ulHashValueLength, rgbHashValue); +} + +TSS_RESULT +Tspi_Hash_GetHashValue(TSS_HHASH hHash, /* in */ + UINT32 * pulHashValueLength, /* out */ + BYTE ** prgbHashValue) /* out */ +{ + if (pulHashValueLength == NULL || prgbHashValue == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + return obj_hash_get_value(hHash, pulHashValueLength, prgbHashValue); +} + +TSS_RESULT +Tspi_Hash_UpdateHashValue(TSS_HHASH hHash, /* in */ + UINT32 ulDataLength, /* in */ + BYTE *rgbData) /* in */ +{ + if (rgbData == NULL && ulDataLength != 0) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (ulDataLength == 0) + return TSS_SUCCESS; + + return obj_hash_update_value(hHash, ulDataLength, rgbData); +} diff --git a/src/tspi/tspi_key.c b/src/tspi/tspi_key.c new file mode 100644 index 0000000..5acd605 --- /dev/null +++ b/src/tspi/tspi_key.c @@ -0,0 +1,706 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" +#include "authsess.h" + + +TSS_RESULT +Tspi_Key_UnloadKey(TSS_HKEY hKey) /* in */ +{ + TSS_HCONTEXT tspContext; + TCS_KEY_HANDLE hTcsKey; + TSS_RESULT result; + + if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext))) + return result; + + if ((result = obj_rsakey_get_tcs_handle(hKey, &hTcsKey))) + return result; + + return __tspi_free_resource(tspContext, hTcsKey, TPM_RT_KEY); +} + +TSS_RESULT +Tspi_Key_LoadKey(TSS_HKEY hKey, /* in */ + TSS_HKEY hUnwrappingKey) /* in */ +{ + TPM_AUTH auth; + TCPA_DIGEST digest; + TSS_RESULT result; + UINT32 keyslot; + TSS_HCONTEXT tspContext; + TSS_HPOLICY hPolicy; + UINT32 keySize; + BYTE *keyBlob; + TCS_KEY_HANDLE tcsKey, tcsParentHandle; + TSS_BOOL usesAuth; + TPM_AUTH *pAuth; + Trspi_HashCtx hashCtx; + TPM_COMMAND_CODE ordinal; + + if (!obj_is_rsakey(hUnwrappingKey)) + return TSPERR(TSS_E_INVALID_HANDLE); + + if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext))) + return result; + + if ((result = obj_context_get_loadkey_ordinal(tspContext, &ordinal))) + return result; + + if ((result = obj_rsakey_get_blob(hKey, &keySize, &keyBlob))) + return result; + + if ((result = obj_rsakey_get_tcs_handle(hUnwrappingKey, &tcsParentHandle))) + return result; + + if ((result = obj_rsakey_get_policy(hUnwrappingKey, TSS_POLICY_USAGE, &hPolicy, + &usesAuth))) { + free_tspi(tspContext, keyBlob); + return result; + } + + if (usesAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, ordinal); + result |= Trspi_HashUpdate(&hashCtx, keySize, keyBlob); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) { + free_tspi(tspContext, keyBlob); + return result; + } + + if ((result = secret_PerformAuth_OIAP(hUnwrappingKey, ordinal, hPolicy, FALSE, + &digest, &auth))) { + free_tspi(tspContext, keyBlob); + return result; + } + pAuth = &auth; + } else { + pAuth = NULL; + } + + if ((result = TCS_API(tspContext)->LoadKeyByBlob(tspContext, tcsParentHandle, keySize, + keyBlob, pAuth, &tcsKey, &keyslot))) { + free_tspi(tspContext, keyBlob); + return result; + } + + free_tspi(tspContext, keyBlob); + + if (usesAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, ordinal); + if (ordinal == TPM_ORD_LoadKey) + result |= Trspi_Hash_UINT32(&hashCtx, keyslot); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth))) + return result; + } + + return obj_rsakey_set_tcs_handle(hKey, tcsKey); +} + +TSS_RESULT +Tspi_Key_GetPubKey(TSS_HKEY hKey, /* in */ + UINT32 * pulPubKeyLength, /* out */ + BYTE ** prgbPubKey) /* out */ +{ + TPM_AUTH auth; + TPM_AUTH *pAuth; + TCPA_DIGEST digest; + TCPA_RESULT result; + TSS_HCONTEXT tspContext; + TSS_HPOLICY hPolicy; + TCS_KEY_HANDLE tcsKeyHandle; + TSS_BOOL usesAuth; + Trspi_HashCtx hashCtx; + + if (pulPubKeyLength == NULL || prgbPubKey == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext))) + return result; + + if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, + &hPolicy, &usesAuth))) + return result; + + if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle))) + return result; + + if (usesAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_GetPubKey); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_GetPubKey, hPolicy, FALSE, + &digest, &auth))) + return result; + pAuth = &auth; + } else { + pAuth = NULL; + } + + if ((result = TCS_API(tspContext)->GetPubKey(tspContext, tcsKeyHandle, pAuth, + pulPubKeyLength, prgbPubKey))) + return result; + + if (usesAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_GetPubKey); + result |= Trspi_HashUpdate(&hashCtx, *pulPubKeyLength, *prgbPubKey); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + /* goto error here since prgbPubKey has been set */ + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth))) + goto error; + } + + if ((result = __tspi_add_mem_entry(tspContext, *prgbPubKey))) + goto error; + + if (tcsKeyHandle == TPM_KEYHND_SRK) + obj_rsakey_set_pubkey(hKey, TRUE, *prgbPubKey); + + return TSS_SUCCESS; +error: + free(*prgbPubKey); + *prgbPubKey = NULL; + *pulPubKeyLength = 0; + return result; +} + +TSS_RESULT +Tspi_Key_CreateKey(TSS_HKEY hKey, /* in */ + TSS_HKEY hWrappingKey, /* in */ + TSS_HPCRS hPcrComposite) /* in, may be NULL */ +{ +#ifdef TSS_BUILD_CMK + UINT32 blobSize; + BYTE *blob; + TSS_BOOL isCmk = FALSE; + TPM_HMAC msaApproval; + TPM_DIGEST msaDigest; +#endif + TCPA_DIGEST digest; + TCPA_RESULT result; + TCS_KEY_HANDLE parentTCSKeyHandle; + BYTE *keyBlob = NULL; + UINT32 keySize; + UINT32 newKeySize; + BYTE *newKey = NULL; + UINT32 ordinal = TPM_ORD_CreateWrapKey; + TSS_HCONTEXT tspContext; + Trspi_HashCtx hashCtx; + struct authsess *xsap = NULL; + + if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext))) + return result; + + if (hPcrComposite) { + /* its possible that hPcrComposite could be a bad handle here, + * or that no indices of it are yet set, which would throw + * internal error. Blanket both those codes with bad + * parameter to help the user out */ + if ((result = obj_rsakey_set_pcr_data(hKey, hPcrComposite))) + return TSPERR(TSS_E_BAD_PARAMETER); + } + + if ((result = obj_rsakey_get_tcs_handle(hWrappingKey, &parentTCSKeyHandle))) + return result; + + if ((result = obj_rsakey_get_blob(hKey, &keySize, &keyBlob))) + return result; + +#ifdef TSS_BUILD_CMK + isCmk = obj_rsakey_is_cmk(hKey); + if (isCmk) { + if ((result = obj_rsakey_get_msa_approval(hKey, &blobSize, &blob))) + goto done; + memcpy(msaApproval.digest, blob, sizeof(msaApproval.digest)); + free_tspi(tspContext, blob); + + if ((result = obj_rsakey_get_msa_digest(hKey, &blobSize, &blob))) + goto done; + memcpy(msaDigest.digest, blob, sizeof(msaDigest.digest)); + free_tspi(tspContext, blob); + + ordinal = TPM_ORD_CMK_CreateKey; + } +#endif + + if ((result = authsess_xsap_init(tspContext, hWrappingKey, hKey, TSS_AUTH_POLICY_REQUIRED, + ordinal, TPM_ET_KEYHANDLE, &xsap))) + return result; + + /* Setup the Hash Data for the HMAC */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, ordinal); +#ifdef TSS_BUILD_CMK + if (isCmk) { + result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata); + result |= Trspi_HashUpdate(&hashCtx, keySize, keyBlob); + result |= Trspi_Hash_HMAC(&hashCtx, msaApproval.digest); + result |= Trspi_Hash_DIGEST(&hashCtx, msaDigest.digest); + } else { +#endif + result |= Trspi_Hash_DIGEST(&hashCtx, xsap->encAuthUse.authdata); + result |= Trspi_Hash_DIGEST(&hashCtx, xsap->encAuthMig.authdata); + result |= Trspi_HashUpdate(&hashCtx, keySize, keyBlob); +#ifdef TSS_BUILD_CMK + } +#endif + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if ((result = authsess_xsap_hmac(xsap, &digest))) + goto done; + + /* Now call the function */ +#ifdef TSS_BUILD_CMK + if (isCmk) { + if ((newKey = malloc(keySize)) == NULL) { + LogError("malloc of %u bytes failed.", keySize); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + memcpy(newKey, keyBlob, keySize); + newKeySize = keySize; + + if ((result = RPC_CMK_CreateKey(tspContext, parentTCSKeyHandle, + (TPM_ENCAUTH *)&xsap->encAuthUse, + &msaApproval, &msaDigest, &newKeySize, &newKey, + xsap->pAuth))) + goto done; + } else { +#endif + if ((result = TCS_API(tspContext)->CreateWrapKey(tspContext, parentTCSKeyHandle, + (TPM_ENCAUTH *)&xsap->encAuthUse, + (TPM_ENCAUTH *)&xsap->encAuthMig, + keySize, keyBlob, &newKeySize, + &newKey, xsap->pAuth))) + goto done; +#ifdef TSS_BUILD_CMK + } +#endif + + /* Validate the Authorization before using the new key */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, ordinal); + result |= Trspi_HashUpdate(&hashCtx, newKeySize, newKey); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if (authsess_xsap_verify(xsap, &digest)) { + result = TSPERR(TSS_E_TSP_AUTHFAIL); + goto done; + } + + /* Push the new key into the existing object */ + result = obj_rsakey_set_tcpakey(hKey, newKeySize, newKey); + +done: + authsess_free(xsap); + free_tspi(tspContext, keyBlob); + free(newKey); + + return result; +} + +TSS_RESULT +Tspi_Key_WrapKey(TSS_HKEY hKey, /* in */ + TSS_HKEY hWrappingKey, /* in */ + TSS_HPCRS hPcrComposite) /* in, may be NULL */ +{ + TSS_HPOLICY hUsePolicy, hMigPolicy; + TCPA_SECRET usage, migration; + TSS_RESULT result; + BYTE *keyPrivBlob = NULL, *wrappingPubKey = NULL, *keyBlob = NULL; + UINT32 keyPrivBlobLen, wrappingPubKeyLen, keyBlobLen; + BYTE newPrivKey[214]; /* its not magic, see TPM 1.1b spec p.71 */ + BYTE encPrivKey[256]; + UINT32 newPrivKeyLen = 214, encPrivKeyLen = 256; + UINT64 offset; + TSS_KEY keyContainer; + TCPA_DIGEST digest; + TSS_HCONTEXT tspContext; + Trspi_HashCtx hashCtx; + + if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext))) + return result; + + if (hPcrComposite) { + if ((result = obj_rsakey_set_pcr_data(hKey, hPcrComposite))) + return result; + } + + /* get the key to be wrapped's private key */ + if ((result = obj_rsakey_get_priv_blob(hKey, &keyPrivBlobLen, &keyPrivBlob))) + goto done; + + /* get the key to be wrapped's blob */ + if ((result = obj_rsakey_get_blob(hKey, &keyBlobLen, &keyBlob))) + goto done; + + /* get the wrapping key's public key */ + if ((result = obj_rsakey_get_modulus(hWrappingKey, &wrappingPubKeyLen, &wrappingPubKey))) + goto done; + + /* get the key to be wrapped's usage policy */ + if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hUsePolicy, NULL))) + goto done; + + if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_MIGRATION, &hMigPolicy, NULL))) + goto done; + + if ((result = obj_policy_get_secret(hUsePolicy, TR_SECRET_CTX_NEW, &usage))) + goto done; + + if ((result = obj_policy_get_secret(hMigPolicy, TR_SECRET_CTX_NEW, &migration))) + goto done; + + memset(&keyContainer, 0, sizeof(TSS_KEY)); + + /* unload the key to be wrapped's blob */ + offset = 0; + if ((result = UnloadBlob_TSS_KEY(&offset, keyBlob, &keyContainer))) + return result; + + /* load the key's attributes into an object and get its hash value */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Hash_TSS_PRIVKEY_DIGEST(&hashCtx, &keyContainer); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + free_key_refs(&keyContainer); + + /* create the plaintext private key blob */ + offset = 0; + Trspi_LoadBlob_BYTE(&offset, TCPA_PT_ASYM, newPrivKey); + Trspi_LoadBlob(&offset, 20, newPrivKey, usage.authdata); + Trspi_LoadBlob(&offset, 20, newPrivKey, migration.authdata); + Trspi_LoadBlob(&offset, 20, newPrivKey, digest.digest); + Trspi_LoadBlob_UINT32(&offset, keyPrivBlobLen, newPrivKey); + Trspi_LoadBlob(&offset, keyPrivBlobLen, newPrivKey, keyPrivBlob); + newPrivKeyLen = offset; + + /* encrypt the private key blob */ + if ((result = Trspi_RSA_Encrypt(newPrivKey, newPrivKeyLen, encPrivKey, + &encPrivKeyLen, wrappingPubKey, + wrappingPubKeyLen))) + goto done; + + /* set the new encrypted private key in the wrapped key object */ + if ((result = obj_rsakey_set_privkey(hKey, FALSE, encPrivKeyLen, encPrivKey))) + goto done; + +done: + free_tspi(tspContext, keyPrivBlob); + free_tspi(tspContext, keyBlob); + free_tspi(tspContext, wrappingPubKey); + return result; +} + +TSS_RESULT +Tspi_Context_LoadKeyByBlob(TSS_HCONTEXT tspContext, /* in */ + TSS_HKEY hUnwrappingKey, /* in */ + UINT32 ulBlobLength, /* in */ + BYTE * rgbBlobData, /* in */ + TSS_HKEY * phKey) /* out */ +{ + TPM_AUTH auth; + UINT64 offset; + TCPA_DIGEST digest; + TSS_RESULT result; + UINT32 keyslot; + TSS_HPOLICY hPolicy; + TCS_KEY_HANDLE tcsParentHandle, myTCSKeyHandle; + TSS_KEY keyContainer; + TSS_BOOL useAuth; + TPM_AUTH *pAuth; + TSS_FLAG initFlags; + UINT16 realKeyBlobSize; + TCPA_KEY_USAGE keyUsage; + UINT32 pubLen; + Trspi_HashCtx hashCtx; + TPM_COMMAND_CODE ordinal; + + if (phKey == NULL || rgbBlobData == NULL ) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (!obj_is_rsakey(hUnwrappingKey)) + return TSPERR(TSS_E_INVALID_HANDLE); + + if ((result = obj_context_get_loadkey_ordinal(tspContext, &ordinal))) + return result; + + if ((result = obj_rsakey_get_tcs_handle(hUnwrappingKey, &tcsParentHandle))) + return result; + + offset = 0; + if ((result = UnloadBlob_TSS_KEY(&offset, rgbBlobData, &keyContainer))) + return result; + realKeyBlobSize = offset; + pubLen = keyContainer.pubKey.keyLength; + keyUsage = keyContainer.keyUsage; + /* free these now, since they're not used below */ + free_key_refs(&keyContainer); + + if ((result = obj_rsakey_get_policy(hUnwrappingKey, TSS_POLICY_USAGE, &hPolicy, &useAuth))) + return result; + + if (useAuth) { + /* Create the Authorization */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, ordinal); + result |= Trspi_HashUpdate(&hashCtx, ulBlobLength, rgbBlobData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hUnwrappingKey, ordinal, hPolicy, FALSE, + &digest, &auth))) + return result; + + pAuth = &auth; + } else { + pAuth = NULL; + } + + if ((result = TCS_API(tspContext)->LoadKeyByBlob(tspContext, tcsParentHandle, ulBlobLength, + rgbBlobData, pAuth, &myTCSKeyHandle, + &keyslot))) + return result; + + if (useAuth) { + /* --- Validate return auth */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, ordinal); + if (ordinal == TPM_ORD_LoadKey) + result |= Trspi_Hash_UINT32(&hashCtx, keyslot); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth))) + return result; + } + + /* --- Create a new Object */ + initFlags = 0; + if (pubLen == 0x100) + initFlags |= TSS_KEY_SIZE_2048; + else if (pubLen == 0x80) + initFlags |= TSS_KEY_SIZE_1024; + else if (pubLen == 0x40) + initFlags |= TSS_KEY_SIZE_512; + + /* clear the key type field */ + initFlags &= ~TSS_KEY_TYPE_MASK; + + if (keyUsage == TPM_KEY_STORAGE) + initFlags |= TSS_KEY_TYPE_STORAGE; + else + initFlags |= TSS_KEY_TYPE_SIGNING; /* loading the blob + will fix this + back to what it + should be. */ + + if ((result = obj_rsakey_add(tspContext, initFlags, phKey))) { + LogDebug("Failed create object"); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + if ((result = obj_rsakey_set_tcpakey(*phKey,realKeyBlobSize, rgbBlobData))) { + LogDebug("Key loaded but failed to setup the key object" + "correctly"); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + return obj_rsakey_set_tcs_handle(*phKey, myTCSKeyHandle); +} + +TSS_RESULT +Tspi_TPM_OwnerGetSRKPubKey(TSS_HTPM hTPM, /* in */ + UINT32 * pulPuKeyLength, /* out */ + BYTE ** prgbPubKey) /* out */ +{ + TSS_RESULT result; + TSS_HPOLICY hPolicy; + TSS_HCONTEXT tspContext; + TCS_KEY_HANDLE hKey; + TPM_AUTH auth; + Trspi_HashCtx hashCtx; + TCPA_DIGEST digest; + + if (pulPuKeyLength == NULL || prgbPubKey == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + hKey = TPM_KEYHND_SRK; + + if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerReadInternalPub); + result |= Trspi_Hash_UINT32(&hashCtx, hKey); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_OwnerReadInternalPub, + hPolicy, FALSE, &digest, &auth))) + return result; + + if ((result = TCS_API(tspContext)->OwnerReadInternalPub(tspContext, hKey, &auth, + pulPuKeyLength, prgbPubKey))) + return result; + + /* Validate return auth */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TSS_SUCCESS); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerReadInternalPub); + result |= Trspi_HashUpdate(&hashCtx, *pulPuKeyLength, *prgbPubKey); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &auth))) + goto error; + + /* Call a special SRK-seeking command to transparently add the public data to the object */ + if ((result = obj_rsakey_set_srk_pubkey(*prgbPubKey))) { + LogError("Error setting SRK public data, SRK key object may not exist"); + } + + if ((result = __tspi_add_mem_entry(tspContext, *prgbPubKey))) + goto error; + + return result; + +error: + free(*prgbPubKey); + pulPuKeyLength = 0; + return result; +} + +/* TSS 1.2-only interfaces */ +#ifdef TSS_BUILD_TSS12 +TSS_RESULT +Tspi_TPM_KeyControlOwner(TSS_HTPM hTPM, /* in */ + TSS_HKEY hTssKey, /* in */ + UINT32 attribName, /* in */ + TSS_BOOL attribValue, /* in */ + TSS_UUID* pUuidData) /* out */ +{ + TSS_RESULT result; + TSS_HPOLICY hPolicy; + TSS_HCONTEXT tspContext; + TCS_KEY_HANDLE hTcsKey; + BYTE *pubKey = NULL; + UINT32 pubKeyLen; + TPM_KEY_CONTROL tpmAttribName; + Trspi_HashCtx hashCtx; + TCPA_DIGEST digest; + TPM_AUTH ownerAuth; + + LogDebugFn("Enter"); + + /* Check valid TPM context, get TSP context */ + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + /* Get Tcs KeyHandle */ + if ((result = obj_rsakey_get_tcs_handle(hTssKey, &hTcsKey))) + return result; + + /* Validate/convert attribName */ + switch (attribName) { + case TSS_TSPATTRIB_KEYCONTROL_OWNEREVICT: + tpmAttribName = TPM_KEY_CONTROL_OWNER_EVICT; + break; + default: + return TSPERR(TSS_E_BAD_PARAMETER); + } + + /* Begin Auth - get TPM Policy Handler */ + if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy))) + return result; + + /* Get associated pubKey */ + if ((result = obj_rsakey_get_pub_blob(hTssKey, &pubKeyLen, &pubKey))) + return result; + + /* Create hash digest */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_KeyControlOwner); + LogDebugData(pubKeyLen, pubKey); + result |= Trspi_HashUpdate(&hashCtx, pubKeyLen, pubKey); + result |= Trspi_Hash_UINT32(&hashCtx, tpmAttribName); + result |= Trspi_Hash_BOOL(&hashCtx, attribValue); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) { + free_tspi(tspContext, pubKey); + return result; + } + + if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_KeyControlOwner, hPolicy, FALSE, + &digest, &ownerAuth))) { + free_tspi(tspContext, pubKey); + return result; + } + + if ((result = RPC_KeyControlOwner(tspContext, hTcsKey, pubKeyLen, pubKey, tpmAttribName, + attribValue, &ownerAuth, pUuidData))) { + free_tspi(tspContext, pubKey); + return result; + } + + /* Validate return auth */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TSS_SUCCESS); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_KeyControlOwner); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &ownerAuth))) + return result; + + /* change hKey internal flag, according to attrib[Name|Value] */ + switch (attribName) { + case TSS_TSPATTRIB_KEYCONTROL_OWNEREVICT: + result = obj_rsakey_set_ownerevict(hTssKey, attribValue); + break; + default: + /* NOT-REACHED */ + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + return result; +} +#endif diff --git a/src/tspi/tspi_maint.c b/src/tspi/tspi_maint.c new file mode 100644 index 0000000..5576ed3 --- /dev/null +++ b/src/tspi/tspi_maint.c @@ -0,0 +1,269 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_TPM_CreateMaintenanceArchive(TSS_HTPM hTPM, /* in */ + TSS_BOOL fGenerateRndNumber, /* in */ + UINT32 * pulRndNumberLength, /* out */ + BYTE ** prgbRndNumber, /* out */ + UINT32 * pulArchiveDataLength, /* out */ + BYTE ** prgbArchiveData) /* out */ +{ + TSS_RESULT result; + TSS_HCONTEXT tspContext; + TSS_HPOLICY hOwnerPolicy; + TPM_AUTH ownerAuth; + TCPA_DIGEST digest; + Trspi_HashCtx hashCtx; + + if (pulArchiveDataLength == NULL || prgbArchiveData == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (fGenerateRndNumber && + (pulRndNumberLength == NULL || prgbRndNumber == NULL)) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hOwnerPolicy))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CreateMaintenanceArchive); + result |= Trspi_Hash_BYTE(&hashCtx, fGenerateRndNumber); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_CreateMaintenanceArchive, hOwnerPolicy, + FALSE, &digest, &ownerAuth))) + return result; + + if ((result = TCS_API(tspContext)->CreateMaintenanceArchive(tspContext, fGenerateRndNumber, + &ownerAuth, pulRndNumberLength, + prgbRndNumber, + pulArchiveDataLength, + prgbArchiveData))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CreateMaintenanceArchive); + result |= Trspi_Hash_UINT32(&hashCtx, *pulRndNumberLength); + result |= Trspi_HashUpdate(&hashCtx, *pulRndNumberLength, *prgbRndNumber); + result |= Trspi_Hash_UINT32(&hashCtx, *pulArchiveDataLength); + result |= Trspi_HashUpdate(&hashCtx, *pulArchiveDataLength, *prgbArchiveData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error1; + + if ((result = obj_policy_validate_auth_oiap(hOwnerPolicy, &digest, &ownerAuth))) + goto error1; + + if ((result = __tspi_add_mem_entry(tspContext, *prgbRndNumber))) + goto error1; + + if ((result = __tspi_add_mem_entry(tspContext, *prgbArchiveData))) { + free_tspi(tspContext, *prgbRndNumber); + goto error2; + } + + return TSS_SUCCESS; +error1: + free(*prgbRndNumber); +error2: + free(*prgbArchiveData); + return result; +} + +TSS_RESULT +Tspi_TPM_KillMaintenanceFeature(TSS_HTPM hTPM) /* in */ +{ + TSS_RESULT result; + TSS_HCONTEXT tspContext; + TSS_HPOLICY hOwnerPolicy; + TPM_AUTH ownerAuth; + TCPA_DIGEST digest; + Trspi_HashCtx hashCtx; + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hOwnerPolicy))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_KillMaintenanceFeature); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_KillMaintenanceFeature, hOwnerPolicy, + FALSE, &digest, &ownerAuth))) + return result; + + if ((result = TCS_API(tspContext)->KillMaintenanceFeature(tspContext, &ownerAuth))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_KillMaintenanceFeature); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = obj_policy_validate_auth_oiap(hOwnerPolicy, &digest, &ownerAuth))) + return result; + + return TSS_SUCCESS; +} + +TSS_RESULT +Tspi_TPM_LoadMaintenancePubKey(TSS_HTPM hTPM, /* in */ + TSS_HKEY hMaintenanceKey, /* in */ + TSS_VALIDATION * pValidationData) /* in, out */ +{ + TSS_RESULT result; + TSS_HCONTEXT tspContext; + TCPA_DIGEST checkSum, digest; + TCPA_NONCE nonce; + UINT64 offset; + UINT32 pubBlobSize; + BYTE hashBlob[512], *pubBlob; + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if (pValidationData == NULL) { + if ((result = get_local_random(tspContext, FALSE, sizeof(TCPA_NONCE), + (BYTE **)nonce.nonce))) + return result; + } else { + if (pValidationData->ulExternalDataLength < sizeof(nonce.nonce)) + return TSPERR(TSS_E_BAD_PARAMETER); + + memcpy(&nonce.nonce, pValidationData->rgbExternalData, sizeof(nonce.nonce)); + } + + if ((result = obj_rsakey_get_pub_blob(hMaintenanceKey, &pubBlobSize, &pubBlob))) + return result; + + if ((result = TCS_API(tspContext)->LoadManuMaintPub(tspContext, nonce, pubBlobSize, pubBlob, + &checkSum))) + return result; + + offset = 0; + Trspi_LoadBlob(&offset, pubBlobSize, hashBlob, pubBlob); + Trspi_LoadBlob(&offset, TCPA_SHA1_160_HASH_LEN, hashBlob, (BYTE *)&nonce.nonce); + + if (pValidationData == NULL) { + if ((result = Trspi_Hash(TSS_HASH_SHA1, offset, hashBlob, digest.digest))) + return result; + + if (memcmp(&digest.digest, &checkSum.digest, TCPA_SHA1_160_HASH_LEN)) + result = TSPERR(TSS_E_FAIL); + } else { + if ((pValidationData->rgbData = calloc_tspi(tspContext, offset)) == NULL) + return TSPERR(TSS_E_OUTOFMEMORY); + + pValidationData->ulDataLength = offset; + memcpy(pValidationData->rgbData, hashBlob, offset); + + if ((pValidationData->rgbValidationData = calloc_tspi(tspContext, + TPM_SHA1_160_HASH_LEN)) + == NULL) { + free_tspi(tspContext, pValidationData->rgbData); + pValidationData->rgbData = NULL; + pValidationData->ulDataLength = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + pValidationData->ulValidationDataLength = TCPA_SHA1_160_HASH_LEN; + + memcpy(pValidationData->rgbValidationData, checkSum.digest, TCPA_SHA1_160_HASH_LEN); + } + + return result; +} + +TSS_RESULT +Tspi_TPM_CheckMaintenancePubKey(TSS_HTPM hTPM, /* in */ + TSS_HKEY hMaintenanceKey, /* in */ + TSS_VALIDATION * pValidationData) /* in, out */ +{ + TSS_RESULT result; + TSS_HCONTEXT tspContext; + TCPA_DIGEST checkSum, digest; + TCPA_NONCE nonce; + UINT32 pubBlobSize; + BYTE *pubBlob; + Trspi_HashCtx hashCtx; + + if ((pValidationData && hMaintenanceKey) || (!pValidationData && !hMaintenanceKey)) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if (pValidationData == NULL) { + if ((result = get_local_random(tspContext, FALSE, sizeof(TCPA_NONCE), + (BYTE **)nonce.nonce))) + return result; + } else { + if (pValidationData->ulExternalDataLength < sizeof(nonce.nonce)) + return TSPERR(TSS_E_BAD_PARAMETER); + + memcpy(&nonce.nonce, pValidationData->rgbExternalData, sizeof(nonce.nonce)); + } + + if ((result = TCS_API(tspContext)->ReadManuMaintPub(tspContext, nonce, &checkSum))) + return result; + + if (pValidationData == NULL) { + if ((result = obj_rsakey_get_pub_blob(hMaintenanceKey, &pubBlobSize, &pubBlob))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_HashUpdate(&hashCtx, pubBlobSize, pubBlob); + result |= Trspi_HashUpdate(&hashCtx, TCPA_SHA1_160_HASH_LEN, (BYTE *)&nonce.nonce); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if (memcmp(&digest.digest, &checkSum.digest, TCPA_SHA1_160_HASH_LEN)) + result = TSPERR(TSS_E_FAIL); + + free_tspi(tspContext, pubBlob); + } else { + /* Ignore Data and DataLength, the application must already have this data. + * Do, however, copy out the checksum so that the application can verify */ + if ((pValidationData->rgbValidationData = calloc_tspi(tspContext, + TCPA_SHA1_160_HASH_LEN)) + == NULL) { + free_tspi(tspContext, pubBlob); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + pValidationData->ulValidationDataLength = TCPA_SHA1_160_HASH_LEN; + memcpy(pValidationData->rgbValidationData, checkSum.digest, TCPA_SHA1_160_HASH_LEN); + } + + return result; +} + diff --git a/src/tspi/tspi_migration.c b/src/tspi/tspi_migration.c new file mode 100644 index 0000000..83b73f4 --- /dev/null +++ b/src/tspi/tspi_migration.c @@ -0,0 +1,400 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_TPM_AuthorizeMigrationTicket(TSS_HTPM hTPM, /* in */ + TSS_HKEY hMigrationKey, /* in */ + TSS_MIGRATION_SCHEME migrationScheme, /* in */ + UINT32 * pulMigTicketLength, /* out */ + BYTE ** prgbMigTicket) /* out */ +{ + UINT64 offset; + TCPA_DIGEST digest; + TCPA_RESULT result; + TSS_HPOLICY hOwnerPolicy; + UINT32 migrationKeySize; + BYTE *migrationKeyBlob; + TSS_KEY tssKey; + BYTE pubKeyBlob[0x1000]; + TPM_AUTH ownerAuth; + UINT32 pubKeySize; + TSS_HCONTEXT tspContext; + UINT32 tpmMigrationScheme; + Trspi_HashCtx hashCtx; + + if (pulMigTicketLength == NULL || prgbMigTicket == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + /* get the tpm Policy */ + if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hOwnerPolicy))) + return result; + + switch (migrationScheme) { + case TSS_MS_MIGRATE: + tpmMigrationScheme = TCPA_MS_MIGRATE; + break; + case TSS_MS_REWRAP: + tpmMigrationScheme = TCPA_MS_REWRAP; + break; + case TSS_MS_MAINT: + tpmMigrationScheme = TCPA_MS_MAINT; + break; +#ifdef TSS_BUILD_CMK + case TSS_MS_RESTRICT_MIGRATE: + tpmMigrationScheme = TPM_MS_RESTRICT_MIGRATE; + break; + + case TSS_MS_RESTRICT_APPROVE_DOUBLE: + tpmMigrationScheme = TPM_MS_RESTRICT_APPROVE_DOUBLE; + break; +#endif + default: + return TSPERR(TSS_E_BAD_PARAMETER); + break; + } + + /* Get the migration key blob */ + if ((result = obj_rsakey_get_blob(hMigrationKey, &migrationKeySize, &migrationKeyBlob))) + return result; + + /* First, turn the keyBlob into a TSS_KEY structure */ + offset = 0; + memset(&tssKey, 0, sizeof(TSS_KEY)); + if ((result = UnloadBlob_TSS_KEY(&offset, migrationKeyBlob, &tssKey))) { + free_tspi(tspContext, migrationKeyBlob); + return result; + } + free_tspi(tspContext, migrationKeyBlob); + + /* Then pull the _PUBKEY portion out of that struct into a blob */ + offset = 0; + Trspi_LoadBlob_KEY_PARMS(&offset, pubKeyBlob, &tssKey.algorithmParms); + Trspi_LoadBlob_STORE_PUBKEY(&offset, pubKeyBlob, &tssKey.pubKey); + pubKeySize = offset; + free_key_refs(&tssKey); + + /* Auth */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_AuthorizeMigrationKey); + result |= Trspi_Hash_UINT16(&hashCtx, tpmMigrationScheme); + result |= Trspi_HashUpdate(&hashCtx, pubKeySize, pubKeyBlob); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_AuthorizeMigrationKey, hOwnerPolicy, + FALSE, &digest, &ownerAuth))) + return result; + + /* Send command */ + if ((result = TCS_API(tspContext)->AuthorizeMigrationKey(tspContext, migrationScheme, + pubKeySize, pubKeyBlob, &ownerAuth, + pulMigTicketLength, + prgbMigTicket))) + return result; + + /* Validate Auth */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_AuthorizeMigrationKey); + result |= Trspi_HashUpdate(&hashCtx, *pulMigTicketLength, *prgbMigTicket); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) { + *pulMigTicketLength = 0; + free(*prgbMigTicket); + return result; + } + + if ((result = obj_policy_validate_auth_oiap(hOwnerPolicy, &digest, &ownerAuth))) { + *pulMigTicketLength = 0; + free(*prgbMigTicket); + return result; + } + + if ((result = __tspi_add_mem_entry(tspContext, *prgbMigTicket))) { + *pulMigTicketLength = 0; + free(*prgbMigTicket); + return result; + } + + return TSS_SUCCESS; +} + +TSS_RESULT +Tspi_Key_CreateMigrationBlob(TSS_HKEY hKeyToMigrate, /* in */ + TSS_HKEY hParentKey, /* in */ + UINT32 ulMigTicketLength, /* in */ + BYTE * rgbMigTicket, /* in */ + UINT32 * pulRandomLength, /* out */ + BYTE ** prgbRandom, /* out */ + UINT32 * pulMigrationBlobLength, /* out */ + BYTE ** prgbMigrationBlob) /* out */ +{ + TPM_AUTH parentAuth, entityAuth; + TPM_AUTH *pParentAuth; + TCPA_RESULT result; + UINT64 offset; + TCPA_DIGEST digest; + UINT32 keyToMigrateSize; + BYTE *keyToMigrateBlob = NULL; + TSS_HPOLICY hParentPolicy; + TSS_HPOLICY hMigratePolicy; + TCPA_MIGRATIONKEYAUTH migAuth; + TSS_KEY tssKey; + TCS_KEY_HANDLE parentHandle; + TSS_BOOL parentUsesAuth; + UINT32 randomSize; + BYTE *random = NULL; + UINT32 blobSize; + BYTE *blob = NULL; + TSS_HCONTEXT tspContext; + Trspi_HashCtx hashCtx; + + memset(&tssKey, 0, sizeof(TSS_KEY)); + + if (pulRandomLength == NULL || prgbRandom == NULL || rgbMigTicket == NULL || + pulMigrationBlobLength == NULL || prgbMigrationBlob == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (!obj_is_rsakey(hKeyToMigrate)) + return TSPERR(TSS_E_INVALID_HANDLE); + + if ((result = obj_rsakey_get_tsp_context(hKeyToMigrate, &tspContext))) + return result; + + if ((result = obj_rsakey_get_blob(hKeyToMigrate, &keyToMigrateSize, &keyToMigrateBlob))) + goto done; + + if ((result = obj_rsakey_get_policy(hParentKey, TSS_POLICY_USAGE, &hParentPolicy, + &parentUsesAuth))) + goto done; + + if ((result = obj_rsakey_get_policy(hKeyToMigrate, TSS_POLICY_MIGRATION, &hMigratePolicy, + NULL))) + goto done; + + /* Parsing the migration scheme from the blob and key object */ + memset(&migAuth, 0, sizeof(TCPA_MIGRATIONKEYAUTH)); + + offset = 0; + if ((result = Trspi_UnloadBlob_MIGRATIONKEYAUTH(&offset, rgbMigTicket, &migAuth))) + goto done; + + /* free these now, since none are used below */ + free(migAuth.migrationKey.algorithmParms.parms); + migAuth.migrationKey.algorithmParms.parmSize = 0; + free(migAuth.migrationKey.pubKey.key); + migAuth.migrationKey.pubKey.keyLength = 0; + + offset = 0; + if ((result = UnloadBlob_TSS_KEY(&offset, keyToMigrateBlob, &tssKey))) + goto done; + + /* Generate the Authorization data */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CreateMigrationBlob); + result |= Trspi_Hash_UINT16(&hashCtx, migAuth.migrationScheme); + result |= Trspi_HashUpdate(&hashCtx, ulMigTicketLength, rgbMigTicket); + result |= Trspi_Hash_UINT32(&hashCtx, tssKey.encSize); + result |= Trspi_HashUpdate(&hashCtx, tssKey.encSize, tssKey.encData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if (parentUsesAuth) { + if ((result = secret_PerformAuth_OIAP(hParentPolicy, TPM_ORD_CreateMigrationBlob, + hParentPolicy, FALSE, &digest, + &parentAuth))) + goto done; + pParentAuth = &parentAuth; + } else { + pParentAuth = NULL; + } + + if ((result = secret_PerformAuth_OIAP(hKeyToMigrate, TPM_ORD_CreateMigrationBlob, + hMigratePolicy, FALSE, &digest, &entityAuth))) + goto done; + + if ((result = obj_rsakey_get_tcs_handle(hParentKey, &parentHandle))) + goto done; + + if ((result = TCS_API(tspContext)->CreateMigrationBlob(tspContext, parentHandle, + migAuth.migrationScheme, + ulMigTicketLength, rgbMigTicket, + tssKey.encSize, tssKey.encData, + pParentAuth, &entityAuth, + &randomSize, &random, + &blobSize, &blob))) + goto done; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CreateMigrationBlob); + result |= Trspi_Hash_UINT32(&hashCtx, randomSize); + result |= Trspi_HashUpdate(&hashCtx, randomSize, random); + result |= Trspi_Hash_UINT32(&hashCtx, blobSize); + result |= Trspi_HashUpdate(&hashCtx, blobSize, blob); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if (parentUsesAuth) { + if ((result = obj_policy_validate_auth_oiap(hParentPolicy, &digest, &parentAuth))) + goto done; + } + + if ((result = obj_policy_validate_auth_oiap(hMigratePolicy, &digest, &entityAuth))) + goto done; + + free(tssKey.encData); + tssKey.encSize = blobSize; + tssKey.encData = blob; + /* Set blob to null since it will now be freed during key ref freeing */ + blob = NULL; + + offset = 0; + LoadBlob_TSS_KEY(&offset, NULL, &tssKey); + + *pulMigrationBlobLength = offset; + *prgbMigrationBlob = calloc_tspi(tspContext, *pulMigrationBlobLength); + if (*prgbMigrationBlob == NULL) { + LogError("malloc of %u bytes failed.", *pulMigrationBlobLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto done; + } + offset = 0; + LoadBlob_TSS_KEY(&offset, *prgbMigrationBlob, &tssKey); + + if (randomSize) { + if ((result = __tspi_add_mem_entry(tspContext, random))) + goto done; + } + *pulRandomLength = randomSize; + *prgbRandom = random; + +done: + if (result) + free(random); + free_tspi(tspContext, keyToMigrateBlob); + free_key_refs(&tssKey); + free(blob); + + return result; +} + +TSS_RESULT +Tspi_Key_ConvertMigrationBlob(TSS_HKEY hKeyToMigrate, /* in */ + TSS_HKEY hParentKey, /* in */ + UINT32 ulRandomLength, /* in */ + BYTE * rgbRandom, /* in */ + UINT32 ulMigrationBlobLength, /* in */ + BYTE * rgbMigrationBlob) /* in */ +{ + TCPA_RESULT result; + TSS_KEY tssKey; + UINT32 outDataSize; + BYTE *outData = NULL; + TCS_KEY_HANDLE parentHandle; + TPM_AUTH parentAuth; + TSS_HPOLICY hParentPolicy; + TCPA_DIGEST digest; + TSS_BOOL useAuth; + TPM_AUTH *pParentAuth; + TSS_HCONTEXT tspContext; + Trspi_HashCtx hashCtx; + UINT64 offset; + + memset(&tssKey, 0, sizeof(TSS_KEY)); + + if ((result = obj_rsakey_get_tsp_context(hKeyToMigrate, &tspContext))) + return result; + + if (!obj_is_rsakey(hParentKey)) + return TSPERR(TSS_E_INVALID_HANDLE); + + /* Get the parent key handle */ + if ((result = obj_rsakey_get_tcs_handle(hParentKey, &parentHandle))) + return result; + + /* Get the policy */ + if ((result = obj_rsakey_get_policy(hParentKey, TSS_POLICY_USAGE, + &hParentPolicy, &useAuth))) + return result; + + offset = 0; + if ((result = UnloadBlob_TSS_KEY(&offset, rgbMigrationBlob, &tssKey))) + return result; + + /* Generate the authorization */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ConvertMigrationBlob); + result |= Trspi_Hash_UINT32(&hashCtx, tssKey.encSize); + result |= Trspi_HashUpdate(&hashCtx, tssKey.encSize, tssKey.encData); + result |= Trspi_Hash_UINT32(&hashCtx, ulRandomLength); + result |= Trspi_HashUpdate(&hashCtx, ulRandomLength, rgbRandom); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if (useAuth) { + if ((result = secret_PerformAuth_OIAP(hParentPolicy, TPM_ORD_ConvertMigrationBlob, + hParentPolicy, FALSE, &digest, &parentAuth))) + goto done; + pParentAuth = &parentAuth; + } else { + pParentAuth = NULL; + } + + if ((result = TCS_API(tspContext)->ConvertMigrationBlob(tspContext, parentHandle, + tssKey.encSize, tssKey.encData, + ulRandomLength, rgbRandom, + pParentAuth, + &outDataSize, &outData))) + goto done; + + /* add validation */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ConvertMigrationBlob); + result |= Trspi_Hash_UINT32(&hashCtx, outDataSize); + result |= Trspi_HashUpdate(&hashCtx, outDataSize, outData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + if (useAuth) { + if ((result = obj_policy_validate_auth_oiap(hParentPolicy, &digest, &parentAuth))) + goto done; + } + + /* Set the key object to the now migrated key */ + if ((result = obj_rsakey_set_tcpakey(hKeyToMigrate, ulMigrationBlobLength, rgbMigrationBlob))) + goto done; + if ((result = obj_rsakey_set_privkey(hKeyToMigrate, TRUE, outDataSize, outData))) + goto done; + result = obj_rsakey_set_tcs_handle(hKeyToMigrate, 0); + +done: + free_key_refs(&tssKey); + free(outData); + + return result; +} diff --git a/src/tspi/tspi_nv.c b/src/tspi/tspi_nv.c new file mode 100644 index 0000000..bdf10ad --- /dev/null +++ b/src/tspi/tspi_nv.c @@ -0,0 +1,527 @@ +/* + * The Initial Developer of the Original Code is Intel Corporation. + * Portions created by Intel Corporation are Copyright (C) 2007 Intel Corporation. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Common Public License as published by + * IBM Corporation; either version 1 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Common Public License for more details. + * + * You should have received a copy of the Common Public License + * along with this program; if not, a copy can be viewed at + * http://www.opensource.org/licenses/cpl1.0.php. + * + * trousers - An open source TCG Software Stack + * + * Author: james.xu@intel.com Rossey.liu@intel.com + * + * Kent Yoder - updates for new authsession mechanism + * (C) International Business Machines Corp. 2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" +#include "authsess.h" + +TSS_RESULT +Tspi_NV_DefineSpace(TSS_HNVSTORE hNvstore, /* in */ + TSS_HPCRS hReadPcrComposite, /* in, may be NULL */ + TSS_HPCRS hWritePcrComposite) /* in, may be NULL*/ +{ + TSS_HCONTEXT tspContext; + TSS_HTPM hTpm; + TSS_RESULT result; + UINT32 uiResultLen; + BYTE *pResult; + UINT32 i; + + TPM_BOOL defined_index = FALSE; + NV_DATA_PUBLIC nv_data_public; + TSS_BOOL need_authdata = FALSE; + TCPA_DIGEST digest; + BYTE *pReadPCR; + UINT32 pReadPCR_len; + BYTE *pWritePCR; + UINT32 pWritePCR_len; + UINT64 NVPublic_DataSize; + BYTE NVPublicData[MAX_PUBLIC_DATA_SIZE]; + Trspi_HashCtx hashCtx; + struct authsess *xsap = NULL; + + if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext))) + return result; + + memset(&nv_data_public, 0, sizeof(NV_DATA_PUBLIC)); + + if ((result = obj_nvstore_get_index(hNvstore, &nv_data_public.nvIndex))) + return result; + + if ((result = obj_nvstore_get_datasize(hNvstore, &nv_data_public.dataSize))) + return result; + + if ((result = obj_nvstore_get_permission(hNvstore, &nv_data_public.permission.attributes))) + return result; + + if ((result = obj_tpm_get(tspContext, &hTpm))) + return result; + + if((result = Tspi_TPM_GetCapability(hTpm, TSS_TPMCAP_NV_LIST, 0, + NULL, &uiResultLen, &pResult))) + return result; + + for (i = 0; i < uiResultLen/sizeof(UINT32); i++) { + if (nv_data_public.nvIndex == Decode_UINT32(pResult + i * sizeof(UINT32))) { + defined_index = TRUE; + break; + } + } + free_tspi(tspContext, pResult); + + if (defined_index) { + result = TSPERR(TSS_E_NV_AREA_EXIST); + return result; + } + + need_authdata = (nv_data_public.permission.attributes + & (TPM_NV_PER_AUTHREAD |TPM_NV_PER_AUTHWRITE)) ? TRUE : FALSE; + + nv_data_public.tag = TPM_TAG_NV_DATA_PUBLIC; + + if ((result = obj_nvstore_create_pcrshortinfo(hNvstore, hReadPcrComposite, + &pReadPCR_len, &pReadPCR))) + return result; + + if ((result = obj_nvstore_create_pcrshortinfo(hNvstore, hWritePcrComposite, + &pWritePCR_len, &pWritePCR))) { + free_tspi(tspContext, pReadPCR); + return result; + } + + NVPublic_DataSize = 0; + Trspi_LoadBlob_UINT16(&NVPublic_DataSize, TPM_TAG_NV_DATA_PUBLIC, NVPublicData); + Trspi_LoadBlob_UINT32(&NVPublic_DataSize, nv_data_public.nvIndex, NVPublicData); + Trspi_LoadBlob(&NVPublic_DataSize, pReadPCR_len, NVPublicData, pReadPCR); + Trspi_LoadBlob(&NVPublic_DataSize, pWritePCR_len, NVPublicData, pWritePCR); + Trspi_LoadBlob_UINT16(&NVPublic_DataSize, TPM_TAG_NV_ATTRIBUTES, NVPublicData); + Trspi_LoadBlob_UINT32(&NVPublic_DataSize, nv_data_public.permission.attributes, NVPublicData); + Trspi_LoadBlob_BOOL(&NVPublic_DataSize, nv_data_public.bReadSTClear, NVPublicData); + Trspi_LoadBlob_BOOL(&NVPublic_DataSize, nv_data_public.bWriteSTClear, NVPublicData); + Trspi_LoadBlob_BOOL(&NVPublic_DataSize, nv_data_public.bWriteDefine, NVPublicData); + Trspi_LoadBlob_UINT32(&NVPublic_DataSize, nv_data_public.dataSize, NVPublicData); + free_tspi(tspContext, pReadPCR); + free_tspi(tspContext, pWritePCR); + + if ((result = authsess_xsap_init(tspContext, hTpm, hNvstore, need_authdata, + TPM_ORD_NV_DefineSpace, TPM_ET_OWNER, &xsap))) { + if (result == TSPERR(TSS_E_TSP_AUTHREQUIRED)) + result = TSS_ERROR_CODE(TSS_E_BAD_PARAMETER); + return result; + } + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_DefineSpace); + result |= Trspi_HashUpdate(&hashCtx, NVPublic_DataSize, NVPublicData); + result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + if ((result = authsess_xsap_hmac(xsap, &digest))) + goto error; + + if ((result = TCS_API(tspContext)->NV_DefineOrReleaseSpace(tspContext, NVPublic_DataSize, + NVPublicData, xsap->encAuthUse, + xsap->pAuth))) + goto error; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_DefineSpace); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + result = authsess_xsap_verify(xsap, &digest); +error: + authsess_free(xsap); + + return result; +} + +TSS_RESULT +Tspi_NV_ReleaseSpace(TSS_HNVSTORE hNvstore) /* in */ +{ + TSS_HCONTEXT tspContext; + TSS_HTPM hTpm; + TSS_RESULT result; + UINT32 uiResultLen; + BYTE *pResult; + UINT32 i; + TPM_BOOL defined_index = FALSE; + NV_DATA_PUBLIC nv_data_public; + TCPA_DIGEST digest; + BYTE *pPCR; + UINT32 pPCR_len; + + UINT64 NVPublic_DataSize; + BYTE NVPublicData[MAX_PUBLIC_DATA_SIZE]; + Trspi_HashCtx hashCtx; + struct authsess *xsap = NULL; + + memset(&nv_data_public, 0, sizeof(NV_DATA_PUBLIC)); + + if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext))) + return result; + + if ((result = obj_nvstore_get_index(hNvstore, &nv_data_public.nvIndex))) + return result; + + if ((result = obj_nvstore_get_datasize(hNvstore, &nv_data_public.dataSize))) + return result; + + if ((result = obj_nvstore_get_permission(hNvstore, &nv_data_public.permission.attributes))) + return result; + + if ((result = obj_tpm_get(tspContext, &hTpm))) + return result; + + if((result = Tspi_TPM_GetCapability(hTpm, TSS_TPMCAP_NV_LIST, 0, + NULL, &uiResultLen, &pResult))) + return result; + + for (i = 0; i < uiResultLen/sizeof(UINT32); i++) { + if (nv_data_public.nvIndex == Decode_UINT32(pResult + i * sizeof(UINT32))) { + defined_index = TRUE; + break; + } + } + free_tspi(tspContext, pResult); + + if (!defined_index) { + result = TSPERR(TSS_E_NV_AREA_NOT_EXIST); + return result; + } + + nv_data_public.tag = TPM_TAG_NV_DATA_PUBLIC; + + if ((result = obj_nvstore_create_pcrshortinfo(hNvstore, NULL_HPCRS, &pPCR_len, &pPCR))) + return result; + + NVPublic_DataSize = 0; + Trspi_LoadBlob_UINT16(&NVPublic_DataSize, TPM_TAG_NV_DATA_PUBLIC, NVPublicData); + Trspi_LoadBlob_UINT32(&NVPublic_DataSize, nv_data_public.nvIndex, NVPublicData); + /* load the read pcr short info */ + Trspi_LoadBlob(&NVPublic_DataSize, pPCR_len, NVPublicData, pPCR); + /* load the write pcr short info */ + Trspi_LoadBlob(&NVPublic_DataSize, pPCR_len, NVPublicData, pPCR); + Trspi_LoadBlob_UINT16(&NVPublic_DataSize, TPM_TAG_NV_ATTRIBUTES, NVPublicData); + Trspi_LoadBlob_UINT32(&NVPublic_DataSize, + nv_data_public.permission.attributes, NVPublicData); + Trspi_LoadBlob_BOOL(&NVPublic_DataSize, nv_data_public.bReadSTClear, NVPublicData); + Trspi_LoadBlob_BOOL(&NVPublic_DataSize, nv_data_public.bWriteSTClear, NVPublicData); + Trspi_LoadBlob_BOOL(&NVPublic_DataSize, nv_data_public.bWriteDefine, NVPublicData); + /*Trspi_LoadBlob_UINT32(&NVPublic_DataSize, nv_data_public.dataSize, NVPublicData);*/ + Trspi_LoadBlob_UINT32(&NVPublic_DataSize, 0, NVPublicData); + free_tspi(tspContext, pPCR); + + if ((result = authsess_xsap_init(tspContext, hTpm, hNvstore, TSS_AUTH_POLICY_NOT_REQUIRED, + TPM_ORD_NV_DefineSpace, TPM_ET_OWNER, &xsap))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_DefineSpace); + result |= Trspi_HashUpdate(&hashCtx, NVPublic_DataSize, NVPublicData); + result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + if ((result = authsess_xsap_hmac(xsap, &digest))) + goto error; + + if ((result = TCS_API(tspContext)->NV_DefineOrReleaseSpace(tspContext, NVPublic_DataSize, + NVPublicData, xsap->encAuthUse, + xsap->pAuth))) + goto error; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_DefineSpace); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + result = authsess_xsap_verify(xsap, &digest); +error: + authsess_free(xsap); + + return result; +} + +TSS_RESULT +Tspi_NV_WriteValue(TSS_HNVSTORE hNvstore, /* in */ + UINT32 offset, /* in */ + UINT32 ulDataLength, /* in */ + BYTE* rgbDataToWrite) /* in */ +{ + TSS_HCONTEXT tspContext; + TSS_HTPM hTpm; + TSS_RESULT result; + NV_DATA_PUBLIC nv_data_public; + UINT32 need_authdata = 0; + UINT32 authwrite =0; + TSS_HPOLICY hPolicy; + TPM_AUTH auth; + TCPA_DIGEST digest; + Trspi_HashCtx hashCtx; + + if ((ulDataLength != 0) && (rgbDataToWrite == NULL)) + return TSPERR(TSS_E_BAD_PARAMETER); + + if((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext))) + return result; + + if ((result = obj_tpm_get(tspContext, &hTpm))) + return result; + + if ((result = obj_nvstore_get_index(hNvstore, &nv_data_public.nvIndex))) + return result; + + if ((result = obj_nvstore_get_policy(hNvstore, TSS_POLICY_USAGE, &hPolicy))) + return result; + + if (hPolicy) { + if ((result = obj_nvstore_get_permission_from_tpm(hNvstore, + &nv_data_public.permission.attributes))) + return result; + + need_authdata = nv_data_public.permission.attributes + & (TPM_NV_PER_AUTHWRITE | TPM_NV_PER_OWNERWRITE); + + authwrite = nv_data_public.permission.attributes & TPM_NV_PER_AUTHWRITE; + + if (need_authdata) { + if (!authwrite) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_WriteValue); + result |= Trspi_Hash_UINT32(&hashCtx, nv_data_public.nvIndex); + result |= Trspi_Hash_UINT32(&hashCtx, offset); + result |= Trspi_Hash_UINT32(&hashCtx, ulDataLength); + result |= Trspi_HashUpdate(&hashCtx, ulDataLength, rgbDataToWrite); + + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hNvstore, + TPM_ORD_NV_WriteValue, + hPolicy, FALSE, &digest, + &auth))) + return result; + + if ((result = TCS_API(tspContext)->NV_WriteValue(tspContext, + nv_data_public.nvIndex, + offset, ulDataLength, + rgbDataToWrite, &auth))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_WriteValue); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, + &digest, &auth))) + return result; + } else { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_WriteValueAuth); + result |= Trspi_Hash_UINT32(&hashCtx, nv_data_public.nvIndex); + result |= Trspi_Hash_UINT32(&hashCtx, offset); + result |= Trspi_Hash_UINT32(&hashCtx, ulDataLength); + result |= Trspi_HashUpdate(&hashCtx, ulDataLength, rgbDataToWrite); + + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hNvstore, + TPM_ORD_NV_WriteValueAuth, + hPolicy, FALSE, &digest, + &auth))) + return result; + + if ((result = TCS_API(tspContext)->NV_WriteValueAuth(tspContext, + nv_data_public.nvIndex, + offset, ulDataLength, + rgbDataToWrite, &auth))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_WriteValueAuth); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, + &digest, &auth))) + return result; + } + } else { + if ((result = TCS_API(tspContext)->NV_WriteValue(tspContext, + nv_data_public.nvIndex, + offset, ulDataLength, + rgbDataToWrite, NULL))) + return result; + } + } else { + LogDebug("no policy, so noauthentication"); + if ((result = TCS_API(tspContext)->NV_WriteValue(tspContext, nv_data_public.nvIndex, + offset, ulDataLength, + rgbDataToWrite, NULL))) + return result; + } + + return result; +} + +TSS_RESULT +Tspi_NV_ReadValue(TSS_HNVSTORE hNvstore, /* in */ + UINT32 offset, /* in */ + UINT32* ulDataLength, /* in, out */ + BYTE** rgbDataRead) /* out */ +{ + TSS_HCONTEXT tspContext; + TSS_HTPM hTpm; + TSS_RESULT result; + NV_DATA_PUBLIC nv_data_public; + UINT32 need_authdata = 0; + UINT32 authread =0; + TSS_HPOLICY hPolicy; + + TPM_AUTH auth; + TCPA_DIGEST digest; + Trspi_HashCtx hashCtx; + + if (ulDataLength == NULL || rgbDataRead == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext))) + return result; + + if ((result = obj_tpm_get(tspContext, &hTpm))) + return result; + + if ((result = obj_nvstore_get_index(hNvstore, &nv_data_public.nvIndex))) + return result; + + if ((result = obj_nvstore_get_policy(hNvstore, TSS_POLICY_USAGE, &hPolicy))) + return result; + + if (hPolicy) {/*if the policy secret is set*/ + if ((result = obj_nvstore_get_permission_from_tpm(hNvstore, + &nv_data_public.permission.attributes))) + return result; + + need_authdata = nv_data_public.permission.attributes + & (TPM_NV_PER_AUTHREAD | TPM_NV_PER_OWNERREAD); + + authread = nv_data_public.permission.attributes & TPM_NV_PER_AUTHREAD; + + if (need_authdata) { + if (!authread) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_ReadValue); + result |= Trspi_Hash_UINT32(&hashCtx, nv_data_public.nvIndex); + result |= Trspi_Hash_UINT32(&hashCtx, offset); + result |= Trspi_Hash_UINT32(&hashCtx, *ulDataLength); + + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hNvstore, + TPM_ORD_NV_ReadValue, + hPolicy, FALSE, &digest, + &auth))) + return result; + + if ((result = TCS_API(tspContext)->NV_ReadValue(tspContext, + nv_data_public.nvIndex, + offset, ulDataLength, + &auth, rgbDataRead))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TSS_SUCCESS); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_ReadValue); + result |= Trspi_Hash_UINT32(&hashCtx, *ulDataLength); + result |= Trspi_HashUpdate(&hashCtx, *ulDataLength, *rgbDataRead); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, + &digest, &auth))) + return result; + } else { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_ReadValueAuth); + result |= Trspi_Hash_UINT32(&hashCtx, nv_data_public.nvIndex); + result |= Trspi_Hash_UINT32(&hashCtx, offset); + result |= Trspi_Hash_UINT32(&hashCtx, *ulDataLength); + + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hNvstore, + TPM_ORD_NV_ReadValueAuth, + hPolicy, FALSE, &digest, + &auth))) + return result; + + if ((result = TCS_API(tspContext)->NV_ReadValueAuth(tspContext, + nv_data_public.nvIndex, + offset, ulDataLength, + &auth, rgbDataRead))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TSS_SUCCESS); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_ReadValueAuth); + result |= Trspi_Hash_UINT32(&hashCtx, *ulDataLength); + result |= Trspi_HashUpdate(&hashCtx, *ulDataLength, *rgbDataRead); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, + &digest, &auth))) + return result; + } + } else { + if ((result = TCS_API(tspContext)->NV_ReadValue(tspContext, + nv_data_public.nvIndex, + offset, ulDataLength, NULL, + rgbDataRead))) + return result; + } + } else { + if ((result = TCS_API(tspContext)->NV_ReadValue(tspContext, nv_data_public.nvIndex, + offset, ulDataLength, NULL, + rgbDataRead))) + return result; + } + + return result; +} diff --git a/src/tspi/tspi_oper.c b/src/tspi/tspi_oper.c new file mode 100644 index 0000000..01db9ff --- /dev/null +++ b/src/tspi/tspi_oper.c @@ -0,0 +1,52 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "obj.h" +#include "tsplog.h" + + +TSS_RESULT +Tspi_TPM_SetOperatorAuth(TSS_HTPM hTpm, /* in */ + TSS_HPOLICY hOperatorPolicy) /* in */ +{ + TSS_HCONTEXT tspContext; + UINT32 type; + TCPA_SECRET operatorAuth; + TSS_RESULT result = TSS_SUCCESS; + + if ((result = obj_tpm_get_tsp_context(hTpm, &tspContext))) + return result; + + if ((result = obj_policy_get_type(hOperatorPolicy, &type))) + return result; + + if (type != TSS_POLICY_OPERATOR) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_policy_get_secret(hOperatorPolicy, TR_SECRET_CTX_NEW, &operatorAuth))) + return result; + + if ((result = TCS_API(tspContext)->SetOperatorAuth(tspContext, &operatorAuth))) + return result; + + if ((result = obj_tpm_set_policy(hTpm, hOperatorPolicy))) + return result; + + return result; +} diff --git a/src/tspi/tspi_own.c b/src/tspi/tspi_own.c new file mode 100644 index 0000000..ef6a44c --- /dev/null +++ b/src/tspi/tspi_own.c @@ -0,0 +1,163 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_TPM_TakeOwnership(TSS_HTPM hTPM, /* in */ + TSS_HKEY hKeySRK, /* in */ + TSS_HKEY hEndorsementPubKey) /* in */ +{ + TPM_AUTH privAuth; + BYTE encOwnerAuth[256]; + UINT32 encOwnerAuthLength; + BYTE encSRKAuth[256]; + UINT32 encSRKAuthLength; + TCPA_DIGEST digest; + TSS_RESULT result; + TSS_HCONTEXT tspContext; + UINT32 srkKeyBlobLength; + BYTE *srkKeyBlob; + TSS_HPOLICY hOwnerPolicy; + UINT32 newSrkBlobSize; + BYTE *newSrkBlob = NULL; + BYTE oldAuthDataUsage; + TSS_HKEY hPubEK; + Trspi_HashCtx hashCtx; + + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if (hEndorsementPubKey == NULL_HKEY) { + if ((result = Tspi_TPM_GetPubEndorsementKey(hTPM, FALSE, NULL, &hPubEK))) { + return result; + } + } else { + hPubEK = hEndorsementPubKey; + } + + /* Get the srkKeyData */ + if ((result = obj_rsakey_get_blob(hKeySRK, &srkKeyBlobLength, &srkKeyBlob))) + return result; + + /* Need to check for Atmel bug where authDataUsage is changed */ + oldAuthDataUsage = srkKeyBlob[10]; + LogDebug("oldAuthDataUsage is %.2X. Wait to see if it changes", oldAuthDataUsage); + + /* Now call the module that will encrypt the secrets. This + * will either get the secrets from the policy objects or + * use the callback function to encrypt the secrets */ + + if ((result = secret_TakeOwnership(hPubEK, hTPM, hKeySRK, &privAuth, &encOwnerAuthLength, + encOwnerAuth, &encSRKAuthLength, encSRKAuth))) + return result; + + /* Now, take ownership is ready to call. The auth structure should be complete + * and the encrypted data structures should be ready */ + if ((result = RPC_TakeOwnership(tspContext, TPM_PID_OWNER, encOwnerAuthLength, encOwnerAuth, + encSRKAuthLength, encSRKAuth, srkKeyBlobLength, srkKeyBlob, + &privAuth, &newSrkBlobSize, &newSrkBlob))) + return result; + + /* The final step is to validate the return Auth */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_TakeOwnership); + result |= Trspi_HashUpdate(&hashCtx, newSrkBlobSize, newSrkBlob); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hOwnerPolicy))) { + free(newSrkBlob); + return result; + } + if ((result = obj_policy_validate_auth_oiap(hOwnerPolicy, &digest, &privAuth))) { + free(newSrkBlob); + return result; + } + + /* Now that it's all happy, stuff the keyBlob into the object + * If atmel, need to adjust the authDataUsage if it changed */ + if (oldAuthDataUsage != newSrkBlob[10]) { /* hardcoded blob stuff */ + LogDebug("auth data usage changed. Atmel bug. Fixing in key object"); + newSrkBlob[10] = oldAuthDataUsage; /* this will fix it */ + } + + result = obj_rsakey_set_tcpakey(hKeySRK, newSrkBlobSize, newSrkBlob); + free(newSrkBlob); + + if (result) + return result; + + /* The SRK is loaded at this point, so insert it into the key handle list */ + return obj_rsakey_set_tcs_handle(hKeySRK, TPM_KEYHND_SRK); +} + +TSS_RESULT +Tspi_TPM_ClearOwner(TSS_HTPM hTPM, /* in */ + TSS_BOOL fForcedClear) /* in */ +{ + TCPA_RESULT result; + TPM_AUTH auth; + TSS_HCONTEXT tspContext; + TCPA_DIGEST hashDigest; + TSS_HPOLICY hPolicy; + Trspi_HashCtx hashCtx; + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if (!fForcedClear) { /* TPM_OwnerClear */ + if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hPolicy))) + return result; + + /* Now do some Hash'ing */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerClear); + if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) + return result; + + /* hashDigest now has the hash result */ + if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_OwnerClear, hPolicy, FALSE, + &hashDigest, &auth))) + return result; + + if ((result = TCS_API(tspContext)->OwnerClear(tspContext, &auth))) + return result; + + /* validate auth */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_OwnerClear); + if ((result |= Trspi_HashFinal(&hashCtx, hashDigest.digest))) + return result; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &hashDigest, &auth))) + return result; + } else { + if ((result = TCS_API(tspContext)->ForceClear(tspContext))) + return result; + } + + return TSS_SUCCESS; +} diff --git a/src/tspi/tspi_pcr_comp.c b/src/tspi/tspi_pcr_comp.c new file mode 100644 index 0000000..e475ee2 --- /dev/null +++ b/src/tspi/tspi_pcr_comp.c @@ -0,0 +1,56 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + +TSS_RESULT +Tspi_PcrComposite_SetPcrValue(TSS_HPCRS hPcrComposite, /* in */ + UINT32 ulPcrIndex, /* in */ + UINT32 ulPcrValueLength, /* in */ + BYTE * rgbPcrValue) /* in */ +{ + if (ulPcrValueLength == 0 || rgbPcrValue == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (ulPcrValueLength != TCPA_SHA1_160_HASH_LEN) + return TSPERR(TSS_E_BAD_PARAMETER); + + return obj_pcrs_set_value(hPcrComposite, ulPcrIndex, ulPcrValueLength, rgbPcrValue); +} + +TSS_RESULT +Tspi_PcrComposite_GetPcrValue(TSS_HPCRS hPcrComposite, /* in */ + UINT32 ulPcrIndex, /* in */ + UINT32 * pulPcrValueLength, /* out */ + BYTE ** prgbPcrValue) /* out */ +{ + if (pulPcrValueLength == NULL || prgbPcrValue == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + return obj_pcrs_get_value(hPcrComposite, ulPcrIndex, pulPcrValueLength, + prgbPcrValue); + +} + +TSS_RESULT +Tspi_PcrComposite_SelectPcrIndex(TSS_HPCRS hPcrComposite, /* in */ + UINT32 ulPcrIndex) /* in */ +{ + return obj_pcrs_select_index(hPcrComposite, ulPcrIndex); +} diff --git a/src/tspi/tspi_pcr_comp12.c b/src/tspi/tspi_pcr_comp12.c new file mode 100644 index 0000000..4133d2b --- /dev/null +++ b/src/tspi/tspi_pcr_comp12.c @@ -0,0 +1,67 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_PcrComposite_SetPcrLocality(TSS_HPCRS hPcrComposite, /* in */ + UINT32 LocalityValue) /* in */ +{ + /* LocalityValue must be some combination of TPM_LOC_* values logically or'd together */ + if (!LocalityValue || (LocalityValue & (~TSS_LOCALITY_ALL))) + return TSPERR(TSS_E_BAD_PARAMETER); + + return obj_pcrs_set_locality(hPcrComposite, LocalityValue); +} + +TSS_RESULT +Tspi_PcrComposite_GetPcrLocality(TSS_HPCRS hPcrComposite, /* in */ + UINT32* pLocalityValue) /* out */ +{ + if (pLocalityValue == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + return obj_pcrs_get_locality(hPcrComposite, pLocalityValue); + +} + +TSS_RESULT +Tspi_PcrComposite_GetCompositeHash(TSS_HPCRS hPcrComposite, /* in */ + UINT32* pLen, /* out */ + BYTE** ppbHashData) /* out */ +{ + if (pLen == NULL || ppbHashData == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + return obj_pcrs_get_digest_at_release(hPcrComposite, pLen, ppbHashData); + +} + +TSS_RESULT +Tspi_PcrComposite_SelectPcrIndexEx(TSS_HPCRS hPcrComposite, /* in */ + UINT32 ulPcrIndex, /* in */ + UINT32 Direction) /* in */ +{ + if (Direction != TSS_PCRS_DIRECTION_CREATION && Direction != TSS_PCRS_DIRECTION_RELEASE) + return TSPERR(TSS_E_BAD_PARAMETER); + + return obj_pcrs_select_index_ex(hPcrComposite, Direction, ulPcrIndex); +} diff --git a/src/tspi/tspi_pcr_events.c b/src/tspi/tspi_pcr_events.c new file mode 100644 index 0000000..c860715 --- /dev/null +++ b/src/tspi/tspi_pcr_events.c @@ -0,0 +1,120 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_TPM_GetEvent(TSS_HTPM hTPM, /* in */ + UINT32 ulPcrIndex, /* in */ + UINT32 ulEventNumber, /* in */ + TSS_PCR_EVENT * pPcrEvent) /* out */ +{ + TSS_HCONTEXT tspContext; + TSS_RESULT result; + TSS_PCR_EVENT *event = NULL; + + if (pPcrEvent == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if ((result = RPC_GetPcrEvent(tspContext, ulPcrIndex, &ulEventNumber, &event))) + return result; + + memcpy(pPcrEvent, event, sizeof(TSS_PCR_EVENT)); + free(event); + + return TSS_SUCCESS; +} + +TSS_RESULT +Tspi_TPM_GetEvents(TSS_HTPM hTPM, /* in */ + UINT32 ulPcrIndex, /* in */ + UINT32 ulStartNumber, /* in */ + UINT32 * pulEventNumber, /* in, out */ + TSS_PCR_EVENT ** prgbPcrEvents) /* out */ +{ + TSS_HCONTEXT tspContext; + TSS_RESULT result; + TSS_PCR_EVENT *events = NULL; + + if (pulEventNumber == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if (prgbPcrEvents) { + if ((result = RPC_GetPcrEventsByPcr(tspContext, ulPcrIndex, ulStartNumber, + pulEventNumber, &events))) + return result; + + *prgbPcrEvents = events; + } else { + /* if the pointer to receive events is NULL, the app only + * wants a total number of events for this PCR. */ + if ((result = RPC_GetPcrEvent(tspContext, ulPcrIndex, pulEventNumber, NULL))) + return result; + } + + return TSS_SUCCESS; +} + +TSS_RESULT +Tspi_TPM_GetEventLog(TSS_HTPM hTPM, /* in */ + UINT32 * pulEventNumber, /* out */ + TSS_PCR_EVENT ** prgbPcrEvents) /* out */ +{ + TSS_HCONTEXT tspContext; + TSS_RESULT result; + + if (pulEventNumber == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + /* if the pointer to receive events is NULL, the app only wants a + * total number of events for all PCRs. */ + if (prgbPcrEvents == NULL) { + UINT16 numPcrs = get_num_pcrs(tspContext); + UINT32 i, numEvents = 0; + + if (numPcrs == 0) { + LogDebugFn("Error querying the TPM for its number of PCRs"); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + *pulEventNumber = 0; + for (i = 0; i < numPcrs; i++) { + if ((result = RPC_GetPcrEvent(tspContext, i, &numEvents, NULL))) + return result; + + *pulEventNumber += numEvents; + } + } else + return RPC_GetPcrEventLog(tspContext, pulEventNumber, prgbPcrEvents); + + return TSS_SUCCESS; +} + diff --git a/src/tspi/tspi_pcr_extend.c b/src/tspi/tspi_pcr_extend.c new file mode 100644 index 0000000..6193fd2 --- /dev/null +++ b/src/tspi/tspi_pcr_extend.c @@ -0,0 +1,158 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * (C) Christian Kummer 2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_TPM_PcrExtend(TSS_HTPM hTPM, /* in */ + UINT32 ulPcrIndex, /* in */ + UINT32 ulPcrDataLength, /* in */ + BYTE *pbPcrData, /* in */ + TSS_PCR_EVENT *pPcrEvent, /* in */ + UINT32 * pulPcrValueLength, /* out */ + BYTE ** prgbPcrValue) /* out */ +{ + TCPA_PCRVALUE outDigest; + TSS_RESULT result; + BYTE *extendData; + TPM_DIGEST digest; + UINT32 number; + TSS_HCONTEXT tspContext; + Trspi_HashCtx hashCtx; + + if (pulPcrValueLength == NULL || prgbPcrValue == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (ulPcrDataLength > 0 && pbPcrData == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if (pPcrEvent) { + /* Create data to extend according to the TSS 1.2 spec section 2.6.2 + * 'TSS_PCR_EVENT', in the 'rgbPcrValue' parameter description. */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, ulPcrIndex); + result |= Trspi_HashUpdate(&hashCtx, ulPcrDataLength, pbPcrData); + result |= Trspi_Hash_UINT32(&hashCtx, pPcrEvent->eventType); + result |= Trspi_HashUpdate(&hashCtx, pPcrEvent->ulEventLength, pPcrEvent->rgbEvent); + if ((result |= Trspi_HashFinal(&hashCtx, (BYTE *)&digest.digest))) + return result; + + extendData = (BYTE *)&digest.digest; + } else { + if (ulPcrDataLength != TPM_SHA1_160_HASH_LEN) + return TSPERR(TSS_E_BAD_PARAMETER); + + extendData = pbPcrData; + } + + if ((result = TCS_API(tspContext)->Extend(tspContext, ulPcrIndex, *(TPM_DIGEST *)extendData, + &outDigest))) + return result; + + /* log the event structure if its passed in */ + if (pPcrEvent) { + /* Set the PCR index in the event struct */ + pPcrEvent->ulPcrIndex = ulPcrIndex; + + if ((pPcrEvent->rgbPcrValue = calloc_tspi(tspContext, + TPM_SHA1_160_HASH_LEN)) == NULL) { + LogError("malloc of %d bytes failed.", TPM_SHA1_160_HASH_LEN); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + memcpy(pPcrEvent->rgbPcrValue, (BYTE *)&digest.digest, TPM_SHA1_160_HASH_LEN); + pPcrEvent->ulPcrValueLength = TPM_SHA1_160_HASH_LEN; + + /* Set the version info in the event struct */ + memcpy(&pPcrEvent->versionInfo, &VERSION_1_1, sizeof(TCPA_VERSION)); + + if ((result = RPC_LogPcrEvent(tspContext, *pPcrEvent, &number))) + return result; + } + + *prgbPcrValue = calloc_tspi(tspContext, sizeof(TPM_PCRVALUE)); + if (*prgbPcrValue == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(TPM_PCRVALUE)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + + memcpy(*prgbPcrValue, &outDigest, sizeof(TPM_PCRVALUE)); + *pulPcrValueLength = sizeof(TPM_PCRVALUE); + + return result; +} + +TSS_RESULT +Tspi_TPM_PcrRead(TSS_HTPM hTPM, /* in */ + UINT32 ulPcrIndex, /* in */ + UINT32 *pulPcrValueLength, /* out */ + BYTE **prgbPcrValue) /* out */ +{ + TCPA_PCRVALUE outDigest; + TSS_RESULT result; + TSS_HCONTEXT tspContext; + + if (pulPcrValueLength == NULL || prgbPcrValue == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if ((result = TCS_API(tspContext)->PcrRead(tspContext, ulPcrIndex, &outDigest))) + return result; + + *prgbPcrValue = calloc_tspi(tspContext, sizeof(TCPA_PCRVALUE)); + if (*prgbPcrValue == NULL) { + LogError("malloc of %zd bytes failed.", sizeof(TCPA_PCRVALUE)); + return TSPERR(TSS_E_OUTOFMEMORY); + } + memcpy(*prgbPcrValue, outDigest.digest, sizeof(TCPA_PCRVALUE)); + *pulPcrValueLength = sizeof(TCPA_PCRVALUE); + + return TSS_SUCCESS; +} + +TSS_RESULT +Tspi_TPM_PcrReset(TSS_HTPM hTPM, /* in */ + TSS_HPCRS hPcrComposite) /* in */ +{ + TSS_RESULT result; + TSS_HCONTEXT tspContext; + UINT32 pcrDataSize; + BYTE pcrData[16]; + + if (!hPcrComposite) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if ((result = obj_pcrs_get_selection(hPcrComposite, &pcrDataSize, pcrData))) + return result; + + return TCS_API(tspContext)->PcrReset(tspContext, pcrDataSize, pcrData); +} + diff --git a/src/tspi/tspi_policy.c b/src/tspi/tspi_policy.c new file mode 100644 index 0000000..ac2c4dd --- /dev/null +++ b/src/tspi/tspi_policy.c @@ -0,0 +1,115 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <errno.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_GetPolicyObject(TSS_HOBJECT hObject, /* in */ + TSS_FLAG policyType, /* in */ + TSS_HPOLICY * phPolicy) /* out */ +{ + TSS_RESULT result; + + if (phPolicy == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (obj_is_tpm(hObject)) { + result = obj_tpm_get_policy(hObject, policyType, phPolicy); +#ifdef TSS_BUILD_NV + } else if (obj_is_nvstore(hObject)) { + result = obj_nvstore_get_policy(hObject, policyType, phPolicy); +#endif +#ifdef TSS_BUILD_RSAKEY_LIST + } else if (obj_is_rsakey(hObject)) { + result = obj_rsakey_get_policy(hObject, policyType, phPolicy, NULL); +#endif +#ifdef TSS_BUILD_ENCDATA_LIST + } else if (obj_is_encdata(hObject)) { + result = obj_encdata_get_policy(hObject, policyType, phPolicy); +#endif + } else { + if (obj_is_policy(hObject) || obj_is_hash(hObject) || + obj_is_pcrs(hObject) || obj_is_context(hObject)) + result = TSPERR(TSS_E_BAD_PARAMETER); + else + result = TSPERR(TSS_E_INVALID_HANDLE); + } + + if (result == TSS_SUCCESS && *phPolicy == NULL_HPOLICY) + result = TSPERR(TSS_E_INTERNAL_ERROR); + + return result; +} + +TSS_RESULT +Tspi_Policy_SetSecret(TSS_HPOLICY hPolicy, /* in */ + TSS_FLAG secretMode, /* in */ + UINT32 ulSecretLength, /* in */ + BYTE * rgbSecret) /* in */ +{ + TSS_RESULT result; + TSS_HCONTEXT tspContext; + + if ((result = obj_policy_get_tsp_context(hPolicy, &tspContext))) + return result; + + if (obj_context_is_silent(tspContext) && secretMode == TSS_SECRET_MODE_POPUP) + return TSPERR(TSS_E_SILENT_CONTEXT); + + return obj_policy_set_secret(hPolicy, secretMode, ulSecretLength, rgbSecret); +} + +TSS_RESULT +Tspi_Policy_FlushSecret(TSS_HPOLICY hPolicy) /* in */ +{ + return obj_policy_flush_secret(hPolicy); +} + +TSS_RESULT +Tspi_Policy_AssignToObject(TSS_HPOLICY hPolicy, /* in */ + TSS_HOBJECT hObject) /* in */ +{ + TSS_RESULT result; + + if (obj_is_tpm(hObject)) { + result = obj_tpm_set_policy(hObject, hPolicy); +#ifdef TSS_BUILD_NV + } else if (obj_is_nvstore(hObject)) { + result = obj_nvstore_set_policy(hObject, hPolicy); +#endif +#ifdef TSS_BUILD_RSAKEY_LIST + } else if (obj_is_rsakey(hObject)) { + result = obj_rsakey_set_policy(hObject, hPolicy); +#endif +#ifdef TSS_BUILD_ENCDATA_LIST + } else if (obj_is_encdata(hObject)) { + result = obj_encdata_set_policy(hObject, hPolicy); +#endif + } else { + result = TSPERR(TSS_E_BAD_PARAMETER); + } + + return result; +} diff --git a/src/tspi/tspi_ps.c b/src/tspi/tspi_ps.c new file mode 100644 index 0000000..b6df78c --- /dev/null +++ b/src/tspi/tspi_ps.c @@ -0,0 +1,581 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "tcs_tsp.h" +#include "tspps.h" +#include "hosttable.h" +#include "tcsd_wrap.h" +#include "tcsd.h" +#include "obj.h" + +TSS_UUID owner_evict_uuid = {0, 0, 0, 0, 0, {0, 0, 0, 0, 1, 0}}; + +TSS_RESULT +Tspi_Context_LoadKeyByUUID(TSS_HCONTEXT tspContext, /* in */ + TSS_FLAG persistentStorageType, /* in */ + TSS_UUID uuidData, /* in */ + TSS_HKEY * phKey) /* out */ +{ + TSS_RESULT result; + TSS_UUID parentUUID; + UINT32 keyBlobSize, parentPSType; + BYTE *keyBlob = NULL; + TCS_KEY_HANDLE tcsKeyHandle; + TSS_HKEY parentTspHandle; + TCS_LOADKEY_INFO info; + UINT32 ulPubKeyLength; + BYTE *rgbPubKey; + TPM_COMMAND_CODE ordinal; + + if (phKey == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((!obj_is_context(tspContext))) + return TSPERR(TSS_E_INVALID_HANDLE); + + if ((result = obj_context_get_loadkey_ordinal(tspContext, &ordinal))) + return result; + + /* This key is in the System Persistant storage */ + if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { +#if 1 + memset(&info, 0, sizeof(TCS_LOADKEY_INFO)); + + result = RPC_LoadKeyByUUID(tspContext, uuidData, &info, &tcsKeyHandle); + + if (TSS_ERROR_CODE(result) == TCS_E_KM_LOADFAILED) { + TSS_HKEY keyHandle; + TSS_HPOLICY hPolicy; + + /* load failed, due to some key in the chain needing auth + * which doesn't yet exist at the TCS level. However, the + * auth may already be set in policies at the TSP level. + * To find out, get the key handle of the key requiring + * auth. First, look at the list of keys in memory. */ + if ((obj_rsakey_get_by_uuid(&info.parentKeyUUID, &keyHandle))) { + /* If that failed, look on disk, in User PS. */ + if (ps_get_key_by_uuid(tspContext, &info.parentKeyUUID, + &keyHandle)) + return result; + } + + if (obj_rsakey_get_policy(keyHandle, TSS_POLICY_USAGE, + &hPolicy, NULL)) + return result; + + if (secret_PerformAuth_OIAP(keyHandle, ordinal, hPolicy, FALSE, + &info.paramDigest, &info.authData)) + return result; + + if ((result = RPC_LoadKeyByUUID(tspContext, uuidData, &info, + &tcsKeyHandle))) + return result; + } else if (result) + return result; + + /*check if provided UUID has an owner evict key UUID prefix */ + if (!memcmp(&uuidData, &owner_evict_uuid, sizeof(TSS_UUID)-1)) { + if ((result = obj_rsakey_add(tspContext, TSS_RSAKEY_FLAG_OWNEREVICT, + phKey))) + return result; + if ((result = obj_rsakey_set_tcs_handle(*phKey, tcsKeyHandle))) + return result; + + //The cached public key portion of the owner evict key is used + //further by TPM_KEY_CONTROLOWNER command for sanity check + if ((result = Tspi_Key_GetPubKey(*phKey, &ulPubKeyLength, &rgbPubKey))) + return result; + + result = obj_rsakey_set_pubkey(*phKey, FALSE, rgbPubKey); + + free(rgbPubKey); + if (result != TSS_SUCCESS) + return result; + } else { + if ((result = RPC_GetRegisteredKeyBlob(tspContext, uuidData, &keyBlobSize, + &keyBlob))) + return result; + + if ((result = obj_rsakey_add_by_key(tspContext, &uuidData, keyBlob, + TSS_OBJ_FLAG_SYSTEM_PS, phKey))) { + free (keyBlob); + return result; + } + + result = obj_rsakey_set_tcs_handle(*phKey, tcsKeyHandle); + + free (keyBlob); + } +#else + if ((result = load_from_system_ps(tspContext, &uuidData, phKey))) + return result; +#endif + } else if (persistentStorageType == TSS_PS_TYPE_USER) { + if ((result = ps_get_parent_uuid_by_uuid(&uuidData, &parentUUID))) + return result; + + /* If the parent is not in memory, recursively call ourselves on it */ + if (obj_rsakey_get_by_uuid(&parentUUID, &parentTspHandle) != TSS_SUCCESS) { + if ((result = ps_get_parent_ps_type_by_uuid(&uuidData, &parentPSType))) + return result; + + if ((result = Tspi_Context_LoadKeyByUUID(tspContext, parentPSType, + parentUUID, &parentTspHandle))) + return result; + } + + if ((result = ps_get_key_by_uuid(tspContext, &uuidData, phKey))) + return result; + + /* The parent is loaded and we have the parent key handle, so call the TCS to + * actually load the child. */ + return Tspi_Key_LoadKey(*phKey, parentTspHandle); + } else { + return TSPERR(TSS_E_BAD_PARAMETER); + } + + return TSS_SUCCESS; +} + +TSS_RESULT +Tspi_Context_RegisterKey(TSS_HCONTEXT tspContext, /* in */ + TSS_HKEY hKey, /* in */ + TSS_FLAG persistentStorageType, /* in */ + TSS_UUID uuidKey, /* in */ + TSS_FLAG persistentStorageTypeParent, /* in */ + TSS_UUID uuidParentKey) /* in */ +{ + BYTE *keyBlob; + UINT32 keyBlobSize; + TSS_RESULT result; + TSS_BOOL answer; + + if (!obj_is_context(tspContext) || !obj_is_rsakey(hKey)) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { + if (persistentStorageTypeParent == TSS_PS_TYPE_USER) { + return TSPERR(TSS_E_NOTIMPL); + } else if (persistentStorageTypeParent == TSS_PS_TYPE_SYSTEM) { + if ((result = obj_rsakey_get_blob(hKey, &keyBlobSize, + &keyBlob))) + return result; + + if ((result = RPC_RegisterKey(tspContext, uuidParentKey, uuidKey, + keyBlobSize, keyBlob, + strlen(PACKAGE_STRING) + 1, + (BYTE *)PACKAGE_STRING))) + return result; + } else { + return TSPERR(TSS_E_BAD_PARAMETER); + } + } else if (persistentStorageType == TSS_PS_TYPE_USER) { + if ((result = ps_is_key_registered(&uuidKey, &answer))) + return result; + + if (answer == TRUE) + return TSPERR(TSS_E_KEY_ALREADY_REGISTERED); + + if ((result = obj_rsakey_get_blob (hKey, &keyBlobSize, &keyBlob))) + return result; + + if ((result = ps_write_key(&uuidKey, &uuidParentKey, + persistentStorageTypeParent, + keyBlobSize, keyBlob))) + return result; + } else { + return TSPERR(TSS_E_BAD_PARAMETER); + } + + if ((result = obj_rsakey_set_uuid(hKey, persistentStorageType, &uuidKey))) + return result; + + return TSS_SUCCESS; +} + +TSS_RESULT +Tspi_Context_UnregisterKey(TSS_HCONTEXT tspContext, /* in */ + TSS_FLAG persistentStorageType, /* in */ + TSS_UUID uuidKey, /* in */ + TSS_HKEY *phKey) /* out */ +{ + BYTE *keyBlob = NULL; + UINT32 keyBlobSize; + TSS_RESULT result; + + if (phKey == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((!obj_is_context(tspContext))) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { + /* get the key first, so it doesn't disappear when we + * unregister it */ + if ((result = RPC_GetRegisteredKeyBlob(tspContext, uuidKey, &keyBlobSize, + &keyBlob))) + return result; + + if ((obj_rsakey_add_by_key(tspContext, &uuidKey, keyBlob, TSS_OBJ_FLAG_SYSTEM_PS, + phKey))) { + free(keyBlob); + return result; + } + + free(keyBlob); + + /* now unregister it */ + if ((result = RPC_UnregisterKey(tspContext, uuidKey))) + return result; + } else if (persistentStorageType == TSS_PS_TYPE_USER) { + /* get the key first, so it doesn't disappear when we + * unregister it */ + if ((result = ps_get_key_by_uuid(tspContext, &uuidKey, phKey))) + return result; + + /* now unregister it */ + if ((result = ps_remove_key(&uuidKey))) + return result; + } else { + return TSPERR(TSS_E_BAD_PARAMETER); + } + + return TSS_SUCCESS; +} + +TSS_RESULT +Tspi_Context_GetKeyByUUID(TSS_HCONTEXT tspContext, /* in */ + TSS_FLAG persistentStorageType, /* in */ + TSS_UUID uuidData, /* in */ + TSS_HKEY * phKey) /* out */ +{ + TCPA_RESULT result; + UINT32 keyBlobSize = 0; + BYTE *keyBlob = NULL; + + if (phKey == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((!obj_is_context(tspContext))) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { + if ((result = RPC_GetRegisteredKeyBlob(tspContext, uuidData, &keyBlobSize, + &keyBlob))) + return result; + + if ((obj_rsakey_add_by_key(tspContext, &uuidData, keyBlob, TSS_OBJ_FLAG_SYSTEM_PS, + phKey))) { + free(keyBlob); + return result; + } + + free(keyBlob); + } else if (persistentStorageType == TSS_PS_TYPE_USER) { + if (!obj_is_context(tspContext)) + return TSPERR(TSS_E_INVALID_HANDLE); + + if ((result = ps_get_key_by_uuid(tspContext, &uuidData, phKey))) + return result; + } else + return TSPERR(TSS_E_BAD_PARAMETER); + + return TSS_SUCCESS; +} + +TSS_RESULT +Tspi_Context_GetKeyByPublicInfo(TSS_HCONTEXT tspContext, /* in */ + TSS_FLAG persistentStorageType, /* in */ + TSS_ALGORITHM_ID algID, /* in */ + UINT32 ulPublicInfoLength, /* in */ + BYTE * rgbPublicInfo, /* in */ + TSS_HKEY * phKey) /* out */ +{ + TCPA_ALGORITHM_ID tcsAlgID; + UINT32 keyBlobSize; + BYTE *keyBlob; + TSS_RESULT result; + TSS_HKEY keyOutHandle; + UINT32 flag = 0; + TSS_KEY keyContainer; + UINT64 offset; + + if (phKey == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (!obj_is_context(tspContext)) + return TSPERR(TSS_E_INVALID_HANDLE); + + switch (algID) { + case TSS_ALG_RSA: + tcsAlgID = TCPA_ALG_RSA; + break; + default: + LogError("Algorithm ID was not type RSA."); + return TSPERR(TSS_E_BAD_PARAMETER); + } + + if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { + if ((result = RPC_GetRegisteredKeyByPublicInfo(tspContext, tcsAlgID, + ulPublicInfoLength, rgbPublicInfo, + &keyBlobSize, &keyBlob))) + return result; + + } else if (persistentStorageType == TSS_PS_TYPE_USER) { + return ps_get_key_by_pub(tspContext, ulPublicInfoLength, rgbPublicInfo, + phKey); + } else + return TSPERR(TSS_E_BAD_PARAMETER); + + /* need to setup the init flags of the create object based on + * the size of the blob's pubkey */ + offset = 0; + if ((result = UnloadBlob_TSS_KEY(&offset, keyBlob, &keyContainer))) { + free(keyBlob); + return result; + } + + /* begin setting up the key object */ + switch (keyContainer.pubKey.keyLength) { + case 16384/8: + flag |= TSS_KEY_SIZE_16384; + break; + case 8192/8: + flag |= TSS_KEY_SIZE_8192; + break; + case 4096/8: + flag |= TSS_KEY_SIZE_4096; + break; + case 2048/8: + flag |= TSS_KEY_SIZE_2048; + break; + case 1024/8: + flag |= TSS_KEY_SIZE_1024; + break; + case 512/8: + flag |= TSS_KEY_SIZE_512; + break; + default: + LogError("Key was not a known keylength."); + free(keyBlob); + free_key_refs(&keyContainer); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + if (keyContainer.keyUsage == TPM_KEY_SIGNING) + flag |= TSS_KEY_TYPE_SIGNING; + else if (keyContainer.keyUsage == TPM_KEY_STORAGE) + flag |= TSS_KEY_TYPE_STORAGE; + else if (keyContainer.keyUsage == TPM_KEY_IDENTITY) + flag |= TSS_KEY_TYPE_IDENTITY; + else if (keyContainer.keyUsage == TPM_KEY_AUTHCHANGE) + flag |= TSS_KEY_TYPE_AUTHCHANGE; + else if (keyContainer.keyUsage == TPM_KEY_BIND) + flag |= TSS_KEY_TYPE_BIND; + else if (keyContainer.keyUsage == TPM_KEY_LEGACY) + flag |= TSS_KEY_TYPE_LEGACY; + + if (keyContainer.authDataUsage == TPM_AUTH_NEVER) + flag |= TSS_KEY_NO_AUTHORIZATION; + else + flag |= TSS_KEY_AUTHORIZATION; + + if (keyContainer.keyFlags & TPM_MIGRATABLE) + flag |= TSS_KEY_MIGRATABLE; + else + flag |= TSS_KEY_NOT_MIGRATABLE; + + if (keyContainer.keyFlags & TPM_VOLATILE) + flag |= TSS_KEY_VOLATILE; + else + flag |= TSS_KEY_NON_VOLATILE; + +#ifdef TSS_BUILD_CMK + if (keyContainer.keyFlags & TPM_MIGRATEAUTHORITY) + flag |= TSS_KEY_CERTIFIED_MIGRATABLE; + else + flag |= TSS_KEY_NOT_CERTIFIED_MIGRATABLE; +#endif + + /* Create a new Key Object */ + if ((result = obj_rsakey_add(tspContext, flag, &keyOutHandle))) { + free(keyBlob); + free_key_refs(&keyContainer); + return result; + } + /* Stick the info into this net KeyObject */ + if ((result = obj_rsakey_set_tcpakey(keyOutHandle, keyBlobSize, keyBlob))) { + free(keyBlob); + free_key_refs(&keyContainer); + return result; + } + + free(keyBlob); + free_key_refs(&keyContainer); + *phKey = keyOutHandle; + + return TSS_SUCCESS; +} + +TSS_RESULT +Tspi_Context_GetRegisteredKeysByUUID(TSS_HCONTEXT tspContext, /* in */ + TSS_FLAG persistentStorageType, /* in */ + TSS_UUID * pUuidData, /* in */ + UINT32 * pulKeyHierarchySize, /* out */ + TSS_KM_KEYINFO ** ppKeyHierarchy) /* out */ +{ + TSS_RESULT result; + TSS_KM_KEYINFO *tcsHier, *tspHier; + UINT32 tcsHierSize, tspHierSize; + TSS_UUID tcs_uuid; + + if (pulKeyHierarchySize == NULL || ppKeyHierarchy == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (!obj_is_context(tspContext)) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (pUuidData) { + if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { + if ((result = RPC_EnumRegisteredKeys(tspContext, pUuidData, + pulKeyHierarchySize, + ppKeyHierarchy))) + return result; + } else if (persistentStorageType == TSS_PS_TYPE_USER) { + if ((result = ps_get_registered_keys(pUuidData, &tcs_uuid, + &tspHierSize, &tspHier))) + return result; + + if ((result = RPC_EnumRegisteredKeys(tspContext, &tcs_uuid, &tcsHierSize, + &tcsHier))) { + free(tspHier); + return result; + } + + result = merge_key_hierarchies(tspContext, tspHierSize, tspHier, + tcsHierSize, tcsHier, pulKeyHierarchySize, + ppKeyHierarchy); + free(tcsHier); + free(tspHier); + } else + return TSPERR(TSS_E_BAD_PARAMETER); + } else { + if ((result = RPC_EnumRegisteredKeys(tspContext, pUuidData, &tcsHierSize, + &tcsHier))) + return result; + + if ((result = ps_get_registered_keys(pUuidData, NULL, &tspHierSize, &tspHier))) { + free(tcsHier); + return result; + } + + result = merge_key_hierarchies(tspContext, tspHierSize, tspHier, tcsHierSize, + tcsHier, pulKeyHierarchySize, ppKeyHierarchy); + free(tcsHier); + free(tspHier); + } + + if ((result = __tspi_add_mem_entry(tspContext, *ppKeyHierarchy))) { + free(*ppKeyHierarchy); + *ppKeyHierarchy = NULL; + *pulKeyHierarchySize = 0; + } + + return result; +} + +TSS_RESULT +Tspi_Context_GetRegisteredKeysByUUID2(TSS_HCONTEXT tspContext, /* in */ + TSS_FLAG persistentStorageType, /* in */ + TSS_UUID * pUuidData, /* in */ + UINT32 * pulKeyHierarchySize, /* out */ + TSS_KM_KEYINFO2 ** ppKeyHierarchy) /* out */ +{ + TSS_RESULT result; + TSS_KM_KEYINFO2 *tcsHier, *tspHier; + UINT32 tcsHierSize, tspHierSize; + TSS_UUID tcs_uuid; + + /* If out parameters are NULL, return error */ + if (pulKeyHierarchySize == NULL || ppKeyHierarchy == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if (!obj_is_context(tspContext)) + return TSPERR(TSS_E_INVALID_HANDLE); + + if (pUuidData) { + /* TSS 1.2 Spec: If a certain key UUID is provided, the returned array of + * TSS_KM_KEYINFO2 structures only contains data reflecting the path of the key + * hierarchy regarding that key. The first array entry is the key addressed by the + * given UUID followed by its parent key up to and including the root key. */ + if (persistentStorageType == TSS_PS_TYPE_SYSTEM) { + if ((result = RPC_EnumRegisteredKeys2(tspContext, pUuidData, + pulKeyHierarchySize, ppKeyHierarchy))) + return result; + } else if (persistentStorageType == TSS_PS_TYPE_USER) { + if ((result = ps_get_registered_keys2(pUuidData, &tcs_uuid, &tspHierSize, + &tspHier))) + return result; + /* The tcs_uuid returned by ps_get_registered_key2 will always be a parent + * of some key into the system ps of a user key into the user ps. This key + * needs to be searched for in the system ps to be merged */ + if ((result = RPC_EnumRegisteredKeys2(tspContext, &tcs_uuid, &tcsHierSize, + &tcsHier))) { + free(tspHier); + return result; + } + + result = merge_key_hierarchies2(tspContext, tspHierSize, tspHier, + tcsHierSize, tcsHier, pulKeyHierarchySize, + ppKeyHierarchy); + free(tcsHier); + free(tspHier); + } else + return TSPERR(TSS_E_BAD_PARAMETER); + } else { + /* If this field is set to NULL, the returned array of TSS_KM_KEYINFO2 structures + * contains data reflecting the entire key hierarchy starting with root key. The + * array will include keys from both the user and the system TSS key store. The + * persistentStorageType field will be ignored. */ + if ((result = RPC_EnumRegisteredKeys2(tspContext, pUuidData, &tcsHierSize, + &tcsHier))) + return result; + + if ((result = ps_get_registered_keys2(pUuidData, NULL, &tspHierSize, &tspHier))) { + free(tcsHier); + return result; + } + + result = merge_key_hierarchies2(tspContext, tspHierSize, tspHier, tcsHierSize, + tcsHier, pulKeyHierarchySize, ppKeyHierarchy); + free(tcsHier); + free(tspHier); + } + + if ((result = __tspi_add_mem_entry(tspContext, *ppKeyHierarchy))) { + free(*ppKeyHierarchy); + *ppKeyHierarchy = NULL; + *pulKeyHierarchySize = 0; + } + + return result; +} diff --git a/src/tspi/tspi_quote.c b/src/tspi/tspi_quote.c new file mode 100644 index 0000000..58d5de0 --- /dev/null +++ b/src/tspi/tspi_quote.c @@ -0,0 +1,217 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_TPM_Quote(TSS_HTPM hTPM, /* in */ + TSS_HKEY hIdentKey, /* in */ + TSS_HPCRS hPcrComposite, /* in */ + TSS_VALIDATION * pValidationData) /* in, out */ +{ + TCPA_RESULT result; + TPM_AUTH privAuth; + TPM_AUTH *pPrivAuth = &privAuth; + UINT64 offset; + TCPA_DIGEST digest; + TCS_KEY_HANDLE tcsKeyHandle; + TSS_HPOLICY hPolicy; + TCPA_NONCE antiReplay; + UINT32 pcrDataSize; + BYTE pcrData[128]; + UINT32 validationLength = 0; + BYTE *validationData = NULL; + UINT32 pcrDataOutSize; + BYTE *pcrDataOut; + UINT32 keyDataSize; + BYTE *keyData; + TSS_KEY keyContainer; + BYTE quoteinfo[1024]; + TSS_BOOL usesAuth; + TSS_HCONTEXT tspContext; + TCPA_VERSION version = {1, 1, 0, 0}; + Trspi_HashCtx hashCtx; + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if (hPcrComposite && !obj_is_pcrs(hPcrComposite)) + return TSPERR(TSS_E_INVALID_HANDLE); + + /* get the identKey Policy */ + if ((result = obj_rsakey_get_policy(hIdentKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth))) + return result; + + /* get the Identity TCS keyHandle */ + if ((result = obj_rsakey_get_tcs_handle(hIdentKey, &tcsKeyHandle))) + return result; + + if (pValidationData == NULL) { + if ((result = get_local_random(tspContext, FALSE, sizeof(TCPA_NONCE), + (BYTE **)antiReplay.nonce))) + return result; + } else { + if (pValidationData->ulExternalDataLength < sizeof(antiReplay.nonce)) + return TSPERR(TSS_E_BAD_PARAMETER); + + memcpy(antiReplay.nonce, pValidationData->rgbExternalData, + sizeof(antiReplay.nonce)); + } + + pcrDataSize = 0; + if (hPcrComposite) { + if ((result = obj_pcrs_get_selection(hPcrComposite, &pcrDataSize, pcrData))) + return result; + } + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Quote); + result |= Trspi_HashUpdate(&hashCtx, TPM_SHA1_160_HASH_LEN, antiReplay.nonce); + result |= Trspi_HashUpdate(&hashCtx, pcrDataSize, pcrData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if (usesAuth) { + if ((result = secret_PerformAuth_OIAP(hIdentKey, TPM_ORD_Quote, hPolicy, FALSE, + &digest, &privAuth))) { + return result; + } + pPrivAuth = &privAuth; + } else { + pPrivAuth = NULL; + } + + if ((result = TCS_API(tspContext)->Quote(tspContext, tcsKeyHandle, &antiReplay, pcrDataSize, + pcrData, pPrivAuth, &pcrDataOutSize, &pcrDataOut, + &validationLength, &validationData))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Quote); + result |= Trspi_HashUpdate(&hashCtx, pcrDataOutSize, pcrDataOut); + result |= Trspi_Hash_UINT32(&hashCtx, validationLength); + result |= Trspi_HashUpdate(&hashCtx, validationLength, validationData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if (usesAuth == TRUE) { + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &privAuth))) { + free(pcrDataOut); + free(validationData); + return result; + } + } + + if (hPcrComposite) { + TCPA_PCR_COMPOSITE pcrComp; + + offset = 0; + if ((result = Trspi_UnloadBlob_PCR_COMPOSITE(&offset, pcrDataOut, &pcrComp))) { + free(pcrDataOut); + free(validationData); + return result; + } + + if ((result = obj_pcrs_set_values(hPcrComposite, &pcrComp))) { + free(pcrDataOut); + free(validationData); + return result; + } + } + + if ((result = Tspi_GetAttribData(hIdentKey, TSS_TSPATTRIB_KEY_BLOB, + TSS_TSPATTRIB_KEYBLOB_BLOB, &keyDataSize, &keyData))) { + free(pcrDataOut); + free(validationData); + return result; + } + + /* create the validation data */ + offset = 0; + memset(&keyContainer, 0, sizeof(TSS_KEY)); + if ((result = UnloadBlob_TSS_KEY(&offset, keyData, &keyContainer))) + return result; + + /* creating pcrCompositeHash */ + Trspi_Hash(TSS_HASH_SHA1, pcrDataOutSize, pcrDataOut, digest.digest); + free(pcrDataOut); + + /* generate Quote_info struct */ + /* 1. add version */ + offset = 0; + if (keyContainer.hdr.key12.tag == TPM_TAG_KEY12) + Trspi_LoadBlob_TCPA_VERSION(&offset, quoteinfo, version); + else + Trspi_LoadBlob_TCPA_VERSION(&offset, quoteinfo, keyContainer.hdr.key11.ver); + /* 2. add "QUOT" */ + quoteinfo[offset++] = 'Q'; + quoteinfo[offset++] = 'U'; + quoteinfo[offset++] = 'O'; + quoteinfo[offset++] = 'T'; + /* 3. Composite Hash */ + Trspi_LoadBlob(&offset, TCPA_SHA1_160_HASH_LEN, quoteinfo, + digest.digest); + /* 4. AntiReplay Nonce */ + Trspi_LoadBlob(&offset, TCPA_SHA1_160_HASH_LEN, quoteinfo, + antiReplay.nonce); + + if (pValidationData == NULL) { + /* validate the data here */ + Trspi_Hash(TSS_HASH_SHA1, offset, quoteinfo, digest.digest); + + if ((result = Trspi_Verify(TSS_HASH_SHA1, digest.digest, 20, + keyContainer.pubKey.key, + keyContainer.pubKey.keyLength, + validationData, + validationLength))) { + free_key_refs(&keyContainer); + free(validationData); + return result; + } + free_key_refs(&keyContainer); + } else { + free_key_refs(&keyContainer); + + pValidationData->rgbValidationData = calloc_tspi(tspContext, validationLength); + if (pValidationData->rgbValidationData == NULL) { + LogError("malloc of %u bytes failed.", validationLength); + return TSPERR(TSS_E_OUTOFMEMORY); + } + pValidationData->ulValidationDataLength = validationLength; + memcpy(pValidationData->rgbValidationData, validationData, validationLength); + free(validationData); + + pValidationData->rgbData = calloc_tspi(tspContext, offset); + if (pValidationData->rgbData == NULL) { + LogError("malloc of %" PRIu64 " bytes failed.", offset); + free_tspi(tspContext, pValidationData->rgbValidationData); + pValidationData->rgbValidationData = NULL; + pValidationData->ulValidationDataLength = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + pValidationData->ulDataLength = (UINT32)offset; + memcpy(pValidationData->rgbData, quoteinfo, offset); + } + + return TSS_SUCCESS; +} diff --git a/src/tspi/tspi_quote2.c b/src/tspi/tspi_quote2.c new file mode 100644 index 0000000..67d4dc1 --- /dev/null +++ b/src/tspi/tspi_quote2.c @@ -0,0 +1,286 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + +TSS_RESULT +Tspi_TPM_Quote2(TSS_HTPM hTPM, // in + TSS_HKEY hIdentKey, // in + TSS_BOOL fAddVersion, // in + TSS_HPCRS hPcrComposite, // in + TSS_VALIDATION* pValidationData, // in, out + UINT32* versionInfoSize, // out + BYTE** versionInfo) // out +{ + TPM_RESULT result; + TSS_HCONTEXT tspContext; + TPM_AUTH privAuth; + TPM_AUTH *pPrivAuth = &privAuth; + UINT64 offset; + TPM_DIGEST digest; + TSS_BOOL usesAuth; + TCS_KEY_HANDLE tcsKeyHandle; + TSS_HPOLICY hPolicy; + TPM_NONCE antiReplay; + UINT32 pcrDataSize; + BYTE pcrData[128]; + UINT32 sigSize = 0; + BYTE *sig = NULL; + UINT32 pcrDataOutSize; + BYTE *pcrDataOut; + BYTE quoteinfo[1024]; + Trspi_HashCtx hashCtx; + + LogDebug("Tspi_TPM_Quote2 Start:"); + + /* Takes the context that this TPM handle is on */ + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + /* Test if the hPcrComposite is valid */ + if ((hPcrComposite) && !obj_is_pcrs(hPcrComposite)) + return TSPERR(TSS_E_INVALID_HANDLE); + + /* get the identKey Policy */ + if ((result = obj_rsakey_get_policy(hIdentKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth))) + return result; + + /* get the Identity TCS keyHandle */ + if ((result = obj_rsakey_get_tcs_handle(hIdentKey, &tcsKeyHandle))) + return result; + + /* Sets the validation data - if NULL, TSS provides it's own random value. If + * not NULL, takes the validation external data and sets the antiReplay data + * with this */ + if (pValidationData == NULL) { + LogDebug("Internal Verify:"); + if ((result = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE), + (BYTE **)antiReplay.nonce))) + return result; + } else { + LogDebug("External Verify:"); + if (pValidationData->ulExternalDataLength < sizeof(antiReplay.nonce)) + return TSPERR(TSS_E_BAD_PARAMETER); + + memcpy(antiReplay.nonce, pValidationData->rgbExternalData, + sizeof(antiReplay.nonce)); + } + + /* Create the TPM_PCR_COMPOSITE object */ + pcrDataSize = 0; + if (hPcrComposite) { + /* Load the PCR Selection Object into the pcrData */ + if ((result = obj_pcrs_get_selection(hPcrComposite, &pcrDataSize, pcrData))) + return result; + } + + if (usesAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Quote2); + result |= Trspi_HashUpdate(&hashCtx, TPM_SHA1_160_HASH_LEN, antiReplay.nonce); + result |= Trspi_HashUpdate(&hashCtx, pcrDataSize, pcrData); + result |= Trspi_Hash_BOOL(&hashCtx,fAddVersion); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + if ((result = secret_PerformAuth_OIAP(hIdentKey, TPM_ORD_Quote2, hPolicy, FALSE, + &digest, &privAuth))) { + return result; + } + pPrivAuth = &privAuth; + } else { + pPrivAuth = NULL; + } + + /* Send to TCS */ + if ((result = TCS_API(tspContext)->Quote2(tspContext, tcsKeyHandle, &antiReplay, + pcrDataSize, pcrData, fAddVersion, pPrivAuth, + &pcrDataOutSize, &pcrDataOut, versionInfoSize, + versionInfo, &sigSize, &sig))) + return result; + +#ifdef TSS_DEBUG + LogDebug("Got TCS Response:"); + LogDebug(" pcrDataOutSize: %u",pcrDataOutSize); + LogDebug(" pcrDataOut:"); + LogDebugData(pcrDataOutSize,pcrDataOut); + LogDebug(" versionInfoSize: %u",*versionInfoSize); + LogDebug(" versionInfo:"); + if (*versionInfoSize >0) + LogDebugData(*versionInfoSize,*versionInfo); + LogDebug(" sigSize: %u",sigSize); + LogDebug(" sig:"); + LogDebugData(sigSize,sig); +#endif + + if (usesAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Quote2); + result |= Trspi_HashUpdate(&hashCtx, pcrDataOutSize, pcrDataOut); + result |= Trspi_Hash_UINT32(&hashCtx,*versionInfoSize); + if (*versionInfoSize > 0) + result |= Trspi_HashUpdate(&hashCtx, *versionInfoSize,*versionInfo); + result |= Trspi_Hash_UINT32(&hashCtx, sigSize); + result |= Trspi_HashUpdate(&hashCtx, sigSize, sig); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) { + free(pcrDataOut); + if (*versionInfoSize > 0) + free(*versionInfo); + free(sig); + return result; + } + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &privAuth))) { + free(pcrDataOut); + if (*versionInfoSize > 0) + free(*versionInfo); + free(sig); + return result; + } + } + + /* Set the pcrDataOut back to the TSS */ + if (hPcrComposite){ + TPM_PCR_INFO_SHORT pcrInfo; + + offset = 0; + if ((result = Trspi_UnloadBlob_PCR_INFO_SHORT(&offset, pcrDataOut, &pcrInfo))) { + free(pcrDataOut); + if (*versionInfoSize > 0) + free(*versionInfo); + free(sig); + return result; + } + + /* Set both digestAtRelease and localityAtRelease */ + if ((result = obj_pcrs_set_locality(hPcrComposite, pcrInfo.localityAtRelease))) { + free(pcrDataOut); + if (*versionInfoSize > 0) + free(*versionInfo); + free(sig); + return result; + } + + if ((result = obj_pcrs_set_digest_at_release(hPcrComposite, + pcrInfo.digestAtRelease))) { + free(pcrDataOut); + if (*versionInfoSize > 0) + free(*versionInfo); + free(sig); + return result; + } + } + + /* generate TPM_QUOTE_INFO2 struct */ + memset("einfo, 0, sizeof(quoteinfo)); + offset = 0; + /* 1. Add Structure TAG */ + quoteinfo[offset++] = 0x00; + quoteinfo[offset++] = (BYTE) TPM_TAG_QUOTE_INFO2; + + /* 2. add "QUT2" */ + quoteinfo[offset++]='Q'; + quoteinfo[offset++]='U'; + quoteinfo[offset++]='T'; + quoteinfo[offset++]='2'; + + /* 3. AntiReplay Nonce - add the external data*/ + Trspi_LoadBlob(&offset, TCPA_SHA1_160_HASH_LEN, quoteinfo, + antiReplay.nonce); + /* 4. add the infoshort TPM_PCR_INFO_SHORT data */ + Trspi_LoadBlob(&offset,pcrDataOutSize,quoteinfo,pcrDataOut); + free(pcrDataOut); + + if (fAddVersion) + Trspi_LoadBlob(&offset,*versionInfoSize,quoteinfo,*versionInfo); + else { + /* versionInfo was not allocated and versionInfoSize has invalid value */ + *versionInfoSize = 0; + *versionInfo = NULL; + } + + LogDebug("TPM_QUOTE_INFO2 data: "); + LogDebugData(offset,quoteinfo); + + if (pValidationData == NULL) { + if ((result = Trspi_Hash(TSS_HASH_SHA1, offset, quoteinfo, digest.digest))) { + free(sig); + if (*versionInfoSize > 0) + free(*versionInfo); + return result; + } + if ((result = __tspi_rsa_verify(hIdentKey,TSS_HASH_SHA1,sizeof(digest.digest), + digest.digest, sigSize, sig))) { + free(sig); + if (*versionInfoSize > 0) + free(*versionInfo); + return TSPERR(TSS_E_VERIFICATION_FAILED); + } + free(sig); + } else { + pValidationData->rgbValidationData = calloc_tspi(tspContext, sigSize); + if (pValidationData->rgbValidationData == NULL) { + LogError("malloc of %u bytes failed.", sigSize); + free(sig); + if (*versionInfoSize > 0) + free(*versionInfo); + return TSPERR(TSS_E_OUTOFMEMORY); + } + pValidationData->ulValidationDataLength = sigSize; + memcpy(pValidationData->rgbValidationData, sig, sigSize); + free(sig); + + pValidationData->rgbData = calloc_tspi(tspContext, offset); + if (pValidationData->rgbData == NULL) { + LogError("malloc of %" PRIu64 " bytes failed.", offset); + free_tspi(tspContext, pValidationData->rgbValidationData); + pValidationData->rgbValidationData = NULL; + pValidationData->ulValidationDataLength = 0; + if (*versionInfoSize > 0) + free(*versionInfo); + return TSPERR(TSS_E_OUTOFMEMORY); + } + pValidationData->ulDataLength = (UINT32)offset; + memcpy(pValidationData->rgbData, quoteinfo, offset); + } + + + if(*versionInfoSize > 0) { + if(fAddVersion) { + /* tag versionInfo so that it can be free'd by the app through Tspi_Context_FreeMemory */ + if ((result = __tspi_add_mem_entry(tspContext, *versionInfo))) { + free_tspi(tspContext, pValidationData->rgbValidationData); + pValidationData->rgbValidationData = NULL; + pValidationData->ulValidationDataLength = 0; + free_tspi(tspContext, pValidationData->rgbData); + pValidationData->rgbData = NULL; + pValidationData->ulDataLength = 0; + free(*versionInfo); + return result; + } + } + else { + free(*versionInfo); + } + } + + LogDebug("Tspi_TPM_Quote2 End"); + return TSS_SUCCESS; +} diff --git a/src/tspi/tspi_random.c b/src/tspi/tspi_random.c new file mode 100644 index 0000000..9fe8c27 --- /dev/null +++ b/src/tspi/tspi_random.c @@ -0,0 +1,74 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_TPM_GetRandom(TSS_HTPM hTPM, /* in */ + UINT32 ulRandomDataLength, /* in */ + BYTE ** prgbRandomData) /* out */ +{ + TSS_HCONTEXT tspContext; + TSS_RESULT result; + + if (prgbRandomData == NULL || ulRandomDataLength > 4096) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if (ulRandomDataLength == 0) + return TSS_SUCCESS; + + if ((result = TCS_API(tspContext)->GetRandom(tspContext, ulRandomDataLength, + prgbRandomData))) + return result; + + if ((result = __tspi_add_mem_entry(tspContext, *prgbRandomData))) { + free(*prgbRandomData); + *prgbRandomData = NULL; + return result; + } + + return TSS_SUCCESS; +} + +TSS_RESULT +Tspi_TPM_StirRandom(TSS_HTPM hTPM, /* in */ + UINT32 ulEntropyDataLength, /* in */ + BYTE * rgbEntropyData) /* in */ +{ + TSS_RESULT result; + TSS_HCONTEXT tspContext; + + if (ulEntropyDataLength > 0 && rgbEntropyData == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if ((result = TCS_API(tspContext)->StirRandom(tspContext, ulEntropyDataLength, + rgbEntropyData))) + return result; + + return TSS_SUCCESS; +} diff --git a/src/tspi/tspi_seal.c b/src/tspi/tspi_seal.c new file mode 100644 index 0000000..95250c6 --- /dev/null +++ b/src/tspi/tspi_seal.c @@ -0,0 +1,327 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" +#include "authsess.h" + + +TSS_RESULT +Tspi_Data_Seal(TSS_HENCDATA hEncData, /* in */ + TSS_HKEY hEncKey, /* in */ + UINT32 ulDataLength, /* in */ + BYTE * rgbDataToSeal, /* in */ + TSS_HPCRS hPcrComposite) /* in */ +{ + TPM_DIGEST digest; + TSS_RESULT result; + TSS_HPOLICY hPolicy, hEncPolicy; + BYTE *encData = NULL; + BYTE *pcrData = NULL; + UINT32 encDataSize; + UINT32 pcrDataSize; + UINT32 pcrInfoType = TSS_PCRS_STRUCT_DEFAULT; + UINT32 sealOrdinal = TPM_ORD_Seal; + TCS_KEY_HANDLE tcsKeyHandle; + TSS_HCONTEXT tspContext; + Trspi_HashCtx hashCtx; + BYTE *sealData = NULL; + struct authsess *xsap = NULL; +#ifdef TSS_BUILD_SEALX + UINT32 protectMode; +#endif + + if (rgbDataToSeal == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_encdata_get_tsp_context(hEncData, &tspContext))) + return result; + + if ((result = obj_rsakey_get_policy(hEncKey, TSS_POLICY_USAGE, + &hPolicy, NULL))) + return result; + + if ((result = obj_encdata_get_policy(hEncData, TSS_POLICY_USAGE, + &hEncPolicy))) + return result; + + if ((result = obj_rsakey_get_tcs_handle(hEncKey, &tcsKeyHandle))) + return result; + +#ifdef TSS_BUILD_SEALX + /* Get the TSS_TSPATTRIB_ENCDATASEAL_PROTECT_MODE attribute + to determine the seal function to invoke */ + if ((result = obj_encdata_get_seal_protect_mode(hEncData, &protectMode))) + return result; + + if (protectMode == TSS_TSPATTRIB_ENCDATASEAL_NO_PROTECT) { + sealOrdinal = TPM_ORD_Seal; + pcrInfoType = 0; + } else if (protectMode == TSS_TSPATTRIB_ENCDATASEAL_PROTECT) { + sealOrdinal = TPM_ORD_Sealx; + pcrInfoType = TSS_PCRS_STRUCT_INFO_LONG; + } else + return TSPERR(TSS_E_INTERNAL_ERROR); +#endif + + /* If PCR's are of interest */ + pcrDataSize = 0; + if (hPcrComposite) { + if ((result = obj_pcrs_create_info_type(hPcrComposite, &pcrInfoType, &pcrDataSize, + &pcrData))) + return result; + } + + if ((result = authsess_xsap_init(tspContext, hEncKey, hEncData, TSS_AUTH_POLICY_REQUIRED, + sealOrdinal, TPM_ET_KEYHANDLE, &xsap))) + goto error; + +#ifdef TSS_BUILD_SEALX + if (sealOrdinal == TPM_ORD_Seal) + sealData = rgbDataToSeal; + else { + if ((sealData = (BYTE *)calloc(1, ulDataLength)) == NULL) { + LogError("malloc of %u bytes failed", ulDataLength); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto error; + } + + if ((result = + ((TSS_RESULT (*)(PVOID, TSS_HKEY, TSS_HENCDATA, TSS_ALGORITHM_ID, + UINT32, BYTE *, BYTE *, BYTE *, BYTE *, UINT32, BYTE *, + BYTE *))xsap->cb_sealx.callback)(xsap->cb_sealx.appData, hEncKey, hEncData, + xsap->cb_sealx.alg, sizeof(TPM_NONCE), + xsap->auth.NonceEven.nonce, + xsap->auth.NonceOdd.nonce, + xsap->nonceEvenxSAP.nonce, + xsap->nonceOddxSAP.nonce, ulDataLength, + rgbDataToSeal, sealData))) + goto error; + } +#else + sealData = rgbDataToSeal; +#endif + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, sealOrdinal); + result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata); + result |= Trspi_Hash_UINT32(&hashCtx, pcrDataSize); + result |= Trspi_HashUpdate(&hashCtx, pcrDataSize, pcrData); + result |= Trspi_Hash_UINT32(&hashCtx, ulDataLength); + result |= Trspi_HashUpdate(&hashCtx, ulDataLength, sealData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) { + goto error; + } + + if ((result = authsess_xsap_hmac(xsap, &digest))) + goto error; + +#ifdef TSS_BUILD_SEALX + if (sealOrdinal == TPM_ORD_Seal) { + if ((result = TCS_API(tspContext)->Seal(tspContext, tcsKeyHandle, &xsap->encAuthUse, + pcrDataSize, pcrData, ulDataLength, + sealData, xsap->pAuth, &encDataSize, + &encData))) { + goto error; + } + } else if (sealOrdinal == TPM_ORD_Sealx) { + if ((result = TCS_API(tspContext)->Sealx(tspContext, tcsKeyHandle, &xsap->encAuthUse, + pcrDataSize, pcrData, ulDataLength, sealData, + xsap->pAuth, &encDataSize, &encData))) { + goto error; + } + } else { + result = TSPERR(TSS_E_INTERNAL_ERROR); + goto error; + } +#else + if ((result = TCS_API(tspContext)->Seal(tspContext, tcsKeyHandle, &xsap->encAuthUse, + pcrDataSize, pcrData, ulDataLength, sealData, + xsap->pAuth, &encDataSize, &encData))) + goto error; +#endif + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, sealOrdinal); + result |= Trspi_HashUpdate(&hashCtx, encDataSize, encData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + if ((result = authsess_xsap_verify(xsap, &digest))) + goto error; + + /* Need to set the object with the blob and the pcr's */ + if ((result = obj_encdata_set_data(hEncData, encDataSize, encData))) + goto error; + + if (pcrDataSize) + result = obj_encdata_set_pcr_info(hEncData, pcrInfoType, pcrData); + +error: + authsess_free(xsap); + free(encData); + free(pcrData); + if (sealData != rgbDataToSeal) + free(sealData); + return result; +} + +TSS_RESULT +Tspi_Data_Unseal(TSS_HENCDATA hEncData, /* in */ + TSS_HKEY hKey, /* in */ + UINT32 * pulUnsealedDataLength,/* out */ + BYTE ** prgbUnsealedData) /* out */ +{ + UINT64 offset; + TPM_AUTH privAuth2; + TPM_DIGEST digest; + TPM_NONCE authLastNonceEven; + TSS_RESULT result; + TSS_HPOLICY hPolicy, hEncPolicy; + TCS_KEY_HANDLE tcsKeyHandle; + TSS_HCONTEXT tspContext; + UINT32 ulDataLen, unSealedDataLen; + BYTE *data = NULL, *unSealedData = NULL, *maskedData; + UINT16 mask; + Trspi_HashCtx hashCtx; + struct authsess *xsap = NULL; + + if (pulUnsealedDataLength == NULL || prgbUnsealedData == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_encdata_get_tsp_context(hEncData, &tspContext))) + return result; + + if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hPolicy, NULL))) + return result; + + if ((result = obj_encdata_get_policy(hEncData, TSS_POLICY_USAGE, &hEncPolicy))) + return result; + + if ((result = obj_encdata_get_data(hEncData, &ulDataLen, &data))) + return result == (TSS_E_INVALID_OBJ_ACCESS | TSS_LAYER_TSP) ? + TSPERR(TSS_E_ENC_NO_DATA) : + result; + + offset = 0; + Trspi_UnloadBlob_UINT16(&offset, &mask, data); + if (mask == TPM_TAG_STORED_DATA12) { + /* The second UINT16 in a TPM_STORED_DATA12 is the entity type. If its non-zero + * then we must unmask the unsealed data after it returns from the TCS */ + Trspi_UnloadBlob_UINT16(&offset, &mask, data); + } else + mask = 0; + + if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle))) + goto error; + + if ((result = authsess_xsap_init(tspContext, hKey, hEncData, TSS_AUTH_POLICY_REQUIRED, + TPM_ORD_Unseal, TPM_ET_KEYHANDLE, &xsap))) + goto error; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Unseal); + result |= Trspi_HashUpdate(&hashCtx, ulDataLen, data); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto error; + + if ((result = authsess_xsap_hmac(xsap, &digest))) + goto error; + + if ((result = secret_PerformAuth_OIAP(hEncData, TPM_ORD_Unseal, hEncPolicy, FALSE, &digest, + &privAuth2))) + goto error; + + if (mask) { + /* save off last nonce even to pass to sealx callback */ + memcpy(authLastNonceEven.nonce, xsap->auth.NonceEven.nonce, sizeof(TPM_NONCE)); + } + + if ((result = TCS_API(tspContext)->Unseal(tspContext, tcsKeyHandle, ulDataLen, data, + xsap->pAuth, &privAuth2, &unSealedDataLen, + &unSealedData))) + goto error; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TSS_SUCCESS); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Unseal); + result |= Trspi_Hash_UINT32(&hashCtx, unSealedDataLen); + result |= Trspi_HashUpdate(&hashCtx, unSealedDataLen, unSealedData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) { + free(unSealedData); + goto error; + } + + if ((result = authsess_xsap_verify(xsap, &digest))) { + free(unSealedData); + goto error; + } + + if ((result = obj_policy_validate_auth_oiap(hEncPolicy, &digest, &privAuth2))) { + free(unSealedData); + goto error; + } + + /* If the data is masked, use the callback set up in authsess_xsap_init */ + if (mask) { + maskedData = unSealedData; + + if ((unSealedData = calloc_tspi(tspContext, unSealedDataLen)) == NULL) { + free(maskedData); + LogError("malloc of %u bytes failed", unSealedDataLen); + result = TSPERR(TSS_E_OUTOFMEMORY); + goto error; + } + + /* XXX pass in out saved-off authLastNonceEven. This conflicts with the + * description of the rgbNonceEven parameter in the spec, but without it, its not + * possible to compute the MGF1 key */ + if ((result = + ((TSS_RESULT (*)(PVOID, TSS_HKEY, TSS_HENCDATA, TSS_ALGORITHM_ID, + UINT32, BYTE *, BYTE *, BYTE *, BYTE *, UINT32, BYTE *, + BYTE *))xsap->cb_sealx.callback)(xsap->cb_sealx.appData, hKey, hEncData, + xsap->cb_sealx.alg, sizeof(TPM_NONCE), + authLastNonceEven.nonce, + xsap->auth.NonceOdd.nonce, + xsap->nonceEvenxSAP.nonce, + xsap->nonceOddxSAP.nonce, + unSealedDataLen, maskedData, + unSealedData))) { + free(maskedData); + goto error; + } + + free(maskedData); + } else { + if ((result = __tspi_add_mem_entry(tspContext, unSealedData))) + goto error; + } + + *pulUnsealedDataLength = unSealedDataLen; + *prgbUnsealedData = unSealedData; + +error: + authsess_free(xsap); + if (data) + free_tspi(tspContext, data); + + return result; +} diff --git a/src/tspi/tspi_selftest.c b/src/tspi/tspi_selftest.c new file mode 100644 index 0000000..2cd31d2 --- /dev/null +++ b/src/tspi/tspi_selftest.c @@ -0,0 +1,206 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_TPM_SelfTestFull(TSS_HTPM hTPM) /* in */ +{ + TSS_RESULT result; + TSS_HCONTEXT tspContext; + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + return TCS_API(tspContext)->SelfTestFull(tspContext); +} + +TSS_RESULT +Tspi_TPM_CertifySelfTest(TSS_HTPM hTPM, /* in */ + TSS_HKEY hKey, /* in */ + TSS_VALIDATION *pValidationData) /* in, out */ +{ + TCPA_RESULT result; + TPM_AUTH keyAuth; + UINT64 offset = 0; + TCPA_DIGEST digest; + TCPA_NONCE antiReplay; + UINT32 outDataSize; + BYTE *outData; + TSS_HPOLICY hPolicy; + TCS_KEY_HANDLE keyTCSKeyHandle; + BYTE *keyData = NULL; + UINT32 keyDataSize; + TSS_KEY keyContainer; + TPM_AUTH *pKeyAuth; + TSS_BOOL useAuth; + TSS_HCONTEXT tspContext; + Trspi_HashCtx hashCtx; + + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, + &hPolicy, &useAuth))) + return result; + + if ((result = obj_rsakey_get_tcs_handle(hKey, &keyTCSKeyHandle))) + return result; + + if (pValidationData == NULL) { + if ((result = get_local_random(tspContext, FALSE, sizeof(TCPA_NONCE), + (BYTE **)antiReplay.nonce))) { + LogError("Failed creating random nonce"); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + } else { + if (pValidationData->ulExternalDataLength < sizeof(antiReplay.nonce)) + return TSPERR(TSS_E_BAD_PARAMETER); + + memcpy(antiReplay.nonce, pValidationData->rgbExternalData, + sizeof(antiReplay.nonce)); + } + + if (useAuth) { + LogDebug("Uses Auth"); + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CertifySelfTest); + result |= Trspi_HashUpdate(&hashCtx, sizeof(TCPA_NONCE), antiReplay.nonce); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_CertifySelfTest, hPolicy, FALSE, + &digest, &keyAuth))) + return result; + pKeyAuth = &keyAuth; + } else { + LogDebug("No Auth"); + pKeyAuth = NULL; + } + + if ((result = TCS_API(tspContext)->CertifySelfTest(tspContext, keyTCSKeyHandle, antiReplay, + pKeyAuth, &outDataSize, &outData))) + return result; + + /* validate auth */ + if (useAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CertifySelfTest); + result |= Trspi_Hash_UINT32(&hashCtx, outDataSize); + result |= Trspi_HashUpdate(&hashCtx, outDataSize, outData); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &keyAuth))) + return result; + } + + if (pValidationData == NULL) { + if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB, + TSS_TSPATTRIB_KEYBLOB_BLOB, &keyDataSize, &keyData))) { + LogError("Failed call to GetAttribData to get key blob"); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + offset = 0; + memset(&keyContainer, 0, sizeof(TSS_KEY)); + if ((result = UnloadBlob_TSS_KEY(&offset, keyData, &keyContainer))) + return result; + + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_HashUpdate(&hashCtx, strlen("Test Passed"), (BYTE *)"Test Passed"); + result |= Trspi_HashUpdate(&hashCtx, sizeof(TCPA_NONCE), antiReplay.nonce); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CertifySelfTest); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + return result; + + if ((result = Trspi_Verify(TSS_HASH_SHA1, digest.digest, 20, + keyContainer.pubKey.key, keyContainer.pubKey.keyLength, + outData, outDataSize))) { + free(outData); + free_key_refs(&keyContainer); + return TSPERR(TSS_E_VERIFICATION_FAILED); + } + + } else { + pValidationData->ulDataLength = sizeof(TCPA_NONCE) + sizeof(UINT32) + + strlen("Test Passed"); + pValidationData->rgbData = calloc_tspi(tspContext, pValidationData->ulDataLength); + if (pValidationData->rgbData == NULL) { + LogError("malloc of %u bytes failed.", pValidationData->ulDataLength); + pValidationData->ulDataLength = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + offset = 0; + Trspi_LoadBlob(&offset, strlen("Test Passed"), pValidationData->rgbData, + (BYTE *)"Test Passed"); + Trspi_LoadBlob(&offset, sizeof(TCPA_NONCE), pValidationData->rgbData, + antiReplay.nonce); + Trspi_LoadBlob_UINT32(&offset, TPM_ORD_CertifySelfTest, pValidationData->rgbData); + pValidationData->ulValidationDataLength = outDataSize; + pValidationData->rgbValidationData = calloc_tspi(tspContext, outDataSize); + if (pValidationData->rgbValidationData == NULL) { + free_tspi(tspContext, pValidationData->rgbData); + pValidationData->rgbData = NULL; + pValidationData->ulDataLength = 0; + LogError("malloc of %u bytes failed.", + pValidationData->ulValidationDataLength); + pValidationData->ulValidationDataLength = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + memcpy(pValidationData->rgbValidationData, outData, outDataSize); + free(outData); + } + + return TSS_SUCCESS; +} + +TSS_RESULT +Tspi_TPM_GetTestResult(TSS_HTPM hTPM, /* in */ + UINT32 * pulTestResultLength, /* out */ + BYTE ** prgbTestResult) /* out */ +{ + TSS_HCONTEXT tspContext; + TSS_RESULT result; + + if (pulTestResultLength == NULL || prgbTestResult == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if ((result = TCS_API(tspContext)->GetTestResult(tspContext, pulTestResultLength, + prgbTestResult))) + return result; + + if ((result = __tspi_add_mem_entry(tspContext, *prgbTestResult))) { + free(*prgbTestResult); + *prgbTestResult = NULL; + *pulTestResultLength = 0; + } + + return TSS_SUCCESS; +} + diff --git a/src/tspi/tspi_sign.c b/src/tspi/tspi_sign.c new file mode 100644 index 0000000..9880cf2 --- /dev/null +++ b/src/tspi/tspi_sign.c @@ -0,0 +1,150 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2006 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + +TSS_RESULT +Tspi_Hash_Sign(TSS_HHASH hHash, /* in */ + TSS_HKEY hKey, /* in */ + UINT32 * pulSignatureLength, /* out */ + BYTE ** prgbSignature) /* out */ +{ + TPM_AUTH privAuth; + TPM_AUTH *pPrivAuth = &privAuth; + TCPA_DIGEST digest; + TCPA_RESULT result; + TSS_HPOLICY hPolicy; + TCS_KEY_HANDLE tcsKeyHandle; + TSS_BOOL usesAuth; + TSS_HCONTEXT tspContext; + UINT32 ulDataLen; + BYTE *data; + Trspi_HashCtx hashCtx; + + if (pulSignatureLength == NULL || prgbSignature == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_hash_get_tsp_context(hHash, &tspContext))) + return result; + + if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth))) + return result; + + if ((result = obj_hash_get_value(hHash, &ulDataLen, &data))) + return result; + + if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle))) + goto done; + + if (usesAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Sign); + result |= Trspi_Hash_UINT32(&hashCtx, ulDataLen); + result |= Trspi_HashUpdate(&hashCtx, ulDataLen, data); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) + goto done; + + pPrivAuth = &privAuth; + + if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_Sign, hPolicy, FALSE, &digest, + &privAuth))) + goto done; + } else { + pPrivAuth = NULL; + } + + if ((result = TCS_API(tspContext)->Sign(tspContext, tcsKeyHandle, ulDataLen, data, + pPrivAuth, pulSignatureLength, prgbSignature))) + goto done; + + if (usesAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Sign); + result |= Trspi_Hash_UINT32(&hashCtx, *pulSignatureLength); + result |= Trspi_HashUpdate(&hashCtx, *pulSignatureLength, *prgbSignature); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) { + free(*prgbSignature); + goto done; + } + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &privAuth))) { + free(*prgbSignature); + goto done; + } + } + + if ((result = __tspi_add_mem_entry(tspContext, *prgbSignature))) + free(*prgbSignature); + +done: + free_tspi(tspContext, data); + return result; +} + +TSS_RESULT +Tspi_Hash_VerifySignature(TSS_HHASH hHash, /* in */ + TSS_HKEY hKey, /* in */ + UINT32 ulSignatureLength, /* in */ + BYTE * rgbSignature) /* in */ +{ + TCPA_RESULT result; + BYTE *pubKey = NULL; + UINT32 pubKeySize; + BYTE *hashData = NULL; + UINT32 hashDataSize; + UINT32 sigScheme; + TSS_HCONTEXT tspContext; + + if (ulSignatureLength > 0 && rgbSignature == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_rsakey_get_tsp_context(hKey, &tspContext))) + return result; + + if ((result = obj_rsakey_get_modulus(hKey, &pubKeySize, &pubKey))) + return result; + + if ((result = obj_rsakey_get_ss(hKey, &sigScheme))) { + free_tspi(tspContext, pubKey); + return result; + } + + if ((result = obj_hash_get_value(hHash, &hashDataSize, &hashData))) { + free_tspi(tspContext, pubKey); + return result; + } + + if (sigScheme == TSS_SS_RSASSAPKCS1V15_SHA1) { + result = Trspi_Verify(TSS_HASH_SHA1, hashData, hashDataSize, pubKey, pubKeySize, + rgbSignature, ulSignatureLength); + } else if (sigScheme == TSS_SS_RSASSAPKCS1V15_DER) { + result = Trspi_Verify(TSS_HASH_OTHER, hashData, hashDataSize, pubKey, pubKeySize, + rgbSignature, ulSignatureLength); + } else { + result = TSPERR(TSS_E_INVALID_SIGSCHEME); + } + + free_tspi(tspContext, pubKey); + free_tspi(tspContext, hashData); + + return result; +} diff --git a/src/tspi/tspi_tick.c b/src/tspi/tspi_tick.c new file mode 100644 index 0000000..65ab07d --- /dev/null +++ b/src/tspi/tspi_tick.c @@ -0,0 +1,178 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_Hash_TickStampBlob(TSS_HHASH hHash, /* in */ + TSS_HKEY hIdentKey, /* in */ + TSS_VALIDATION* pValidationData) /* in */ +{ + TSS_RESULT result; + TSS_HCONTEXT tspContext; + TCS_KEY_HANDLE tcsKey; + TSS_HPOLICY hPolicy; + TPM_DIGEST digest; + TSS_BOOL usesAuth; + TPM_AUTH auth, *pAuth; + UINT32 hashLen, sigLen, tcLen, signInfoLen; + BYTE *hash, *sig, *tc, *signInfo = NULL; + UINT64 offset; + Trspi_HashCtx hashCtx; + + if (pValidationData == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_hash_get_tsp_context(hHash, &tspContext))) + return result; + + if (pValidationData->ulExternalDataLength != sizeof(TPM_NONCE)) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_hash_get_value(hHash, &hashLen, &hash))) + return result; + + if (hashLen != sizeof(TPM_DIGEST)) { + free_tspi(tspContext, hash); + return TSPERR(TSS_E_HASH_INVALID_LENGTH); + } + + if ((result = obj_rsakey_get_policy(hIdentKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth))) + return result; + + if ((result = obj_rsakey_get_tcs_handle(hIdentKey, &tcsKey))) + return result; + + if (usesAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_TickStampBlob); + result |= Trspi_HashUpdate(&hashCtx, sizeof(TPM_NONCE), + pValidationData->rgbExternalData); + result |= Trspi_HashUpdate(&hashCtx, sizeof(TPM_DIGEST), hash); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) { + free_tspi(tspContext, hash); + return result; + } + + if ((result = secret_PerformAuth_OIAP(hIdentKey, TPM_ORD_TickStampBlob, hPolicy, + FALSE, &digest, &auth))) { + free_tspi(tspContext, hash); + return result; + } + pAuth = &auth; + } else + pAuth = NULL; + + if ((result = TCS_API(tspContext)->TickStampBlob(tspContext, tcsKey, + (TPM_NONCE *)pValidationData->rgbExternalData, + (TPM_DIGEST *)hash, pAuth, &sigLen, &sig, &tcLen, + &tc))) { + free_tspi(tspContext, hash); + return result; + } + + if (usesAuth) { + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_UINT32(&hashCtx, result); + result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_TickStampBlob); + result |= Trspi_HashUpdate(&hashCtx, tcLen, tc); + result |= Trspi_Hash_UINT32(&hashCtx, sigLen); + result |= Trspi_HashUpdate(&hashCtx, sigLen, sig); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) { + free_tspi(tspContext, hash); + free(sig); + free(tc); + return result; + } + + if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth))) { + free_tspi(tspContext, hash); + free(sig); + free(tc); + return result; + } + } + + /* tag fixed replay length(Data) Data */ + signInfoLen = sizeof(UINT16) + 4 + sizeof(TPM_NONCE) + sizeof(UINT32) + sizeof(TPM_DIGEST) + tcLen; + if ((signInfo = calloc_tspi(tspContext, signInfoLen)) == NULL) { + free_tspi(tspContext, hash); + free(sig); + free(tc); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + offset = 0; + Trspi_LoadBlob_UINT16(&offset, TPM_TAG_SIGNINFO, signInfo); + Trspi_LoadBlob_BYTE(&offset, 'T', signInfo); + Trspi_LoadBlob_BYTE(&offset, 'S', signInfo); + Trspi_LoadBlob_BYTE(&offset, 'T', signInfo); + Trspi_LoadBlob_BYTE(&offset, 'P', signInfo); + Trspi_LoadBlob(&offset, sizeof(TPM_NONCE), signInfo, pValidationData->rgbExternalData); + Trspi_LoadBlob_UINT32(&offset, sizeof(TPM_DIGEST) + tcLen, signInfo); + Trspi_LoadBlob(&offset, sizeof(TPM_DIGEST), signInfo, hash); + Trspi_LoadBlob(&offset, (size_t)tcLen, signInfo, tc); + + free(tc); + free_tspi(tspContext, hash); + + pValidationData->rgbData = signInfo; + pValidationData->ulDataLength = signInfoLen; + + /* tag sig so that it can be free'd by the app through Tspi_Context_FreeMemory */ + if ((result = __tspi_add_mem_entry(tspContext, sig))) { + free_tspi(tspContext, signInfo); + free(sig); + return result; + } + + pValidationData->rgbValidationData = sig; + pValidationData->ulValidationDataLength = sigLen; + + return TSS_SUCCESS; +} + +TSS_RESULT +Tspi_TPM_ReadCurrentTicks(TSS_HTPM hTPM, /* in */ + TPM_CURRENT_TICKS* tickCount) /* out */ +{ + TSS_RESULT result; + TSS_HCONTEXT tspContext; + UINT32 tcLen; + BYTE *tc; + UINT64 offset; + + if (tickCount == NULL) + return TSPERR(TSS_E_BAD_PARAMETER); + + if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext))) + return result; + + if ((result = TCS_API(tspContext)->ReadCurrentTicks(tspContext, &tcLen, &tc))) + return result; + + offset = 0; + Trspi_UnloadBlob_CURRENT_TICKS(&offset, tc, tickCount); + free(tc); + + return result; +} diff --git a/src/tspi/tspi_transport.c b/src/tspi/tspi_transport.c new file mode 100644 index 0000000..bd956cd --- /dev/null +++ b/src/tspi/tspi_transport.c @@ -0,0 +1,119 @@ + +/* + * Licensed Materials - Property of IBM + * + * trousers - An open source TCG Software Stack + * + * (C) Copyright International Business Machines Corp. 2004-2007 + * + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <inttypes.h> + +#include "trousers/tss.h" +#include "trousers/trousers.h" +#include "trousers_types.h" +#include "spi_utils.h" +#include "capabilities.h" +#include "tsplog.h" +#include "obj.h" + + +TSS_RESULT +Tspi_Context_SetTransEncryptionKey(TSS_HCONTEXT hContext, /* in */ + TSS_HKEY hIdentKey) /* in */ +{ + if (!obj_is_rsakey(hIdentKey)) + return TSPERR(TSS_E_INVALID_HANDLE); + + return obj_context_set_transport_key(hContext, hIdentKey); +} + +TSS_RESULT +Tspi_Context_CloseSignTransport(TSS_HCONTEXT hContext, /* in */ + TSS_HKEY hSigningKey, /* in */ + TSS_VALIDATION* pValidationData) /* in, out */ +{ + TSS_RESULT result; + TSS_HPOLICY hPolicy; + TSS_BOOL usesAuth; + UINT32 sigLen; + BYTE *sig; + UINT64 offset; + Trspi_HashCtx hashCtx; + TPM_DIGEST digest; + TPM_SIGN_INFO signInfo; + + if (!obj_is_context(hContext)) + return TSPERR(TSS_E_INVALID_HANDLE); + + if ((result = obj_rsakey_get_policy(hSigningKey, TSS_POLICY_USAGE, &hPolicy, &usesAuth))) + return result; + + if (pValidationData) { + if (pValidationData->ulExternalDataLength != sizeof(TPM_NONCE)) + return TSPERR(TSS_E_BAD_PARAMETER); + + memcpy(signInfo.replay.nonce, pValidationData->rgbExternalData, sizeof(TPM_NONCE)); + } else { + if ((result = get_local_random(hContext, FALSE, sizeof(TPM_NONCE), + (BYTE **)&signInfo.replay.nonce))) + return result; + } + + /* the transport sessions properties are kept in the context object itself, so just pass + * in what this function provides and let it call ReleaseTransportSigned */ + if ((result = obj_context_transport_close(hContext, hSigningKey, hPolicy, usesAuth, + &signInfo, &sigLen, &sig))) + return result; + + /* inside obj_context_transport_close we set up all the fields of the sign info structure + * other than the tag and 'fixed' */ + signInfo.tag = TPM_TAG_SIGNINFO; + signInfo.fixed[0] = 'T'; + signInfo.fixed[1] = 'R'; + signInfo.fixed[2] = 'A'; + signInfo.fixed[3] = 'N'; + + /* hash the sign info struct for use in verifying the TPM's signature */ + result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1); + result |= Trspi_Hash_SIGN_INFO(&hashCtx, &signInfo); + if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) { + free(sig); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + + offset = 0; + if (pValidationData) { + /* tag the returned allocated memory as alloc'd by the TSP */ + if ((result = __tspi_add_mem_entry(hContext, sig))) { + free(sig); + return TSPERR(TSS_E_INTERNAL_ERROR); + } + pValidationData->rgbValidationData = sig; + pValidationData->ulValidationDataLength = sigLen; + + /* passing a NULL blob here puts the exact size of TPM_SIGN_INFO into offset */ + Trspi_LoadBlob_SIGN_INFO(&offset, NULL, &signInfo); + pValidationData->rgbData = calloc_tspi(hContext, offset); + if (pValidationData->rgbData == NULL) { + LogError("malloc of %" PRIu64 " bytes failed.", offset); + free_tspi(hContext, pValidationData->rgbValidationData); + pValidationData->rgbValidationData = NULL; + pValidationData->ulValidationDataLength = 0; + return TSPERR(TSS_E_OUTOFMEMORY); + } + pValidationData->ulDataLength = (UINT32)offset; + + offset = 0; + Trspi_LoadBlob_SIGN_INFO(&offset, pValidationData->rgbData, &signInfo); + } else + result = __tspi_rsa_verify(hSigningKey, TSS_HASH_SHA1, sizeof(TPM_DIGEST), digest.digest, + sigLen, sig); + + return result; +} |