summaryrefslogtreecommitdiff
path: root/src/tspi
diff options
context:
space:
mode:
Diffstat (limited to 'src/tspi')
-rw-r--r--src/tspi/Makefile.am235
-rw-r--r--src/tspi/Makefile.in2030
-rw-r--r--src/tspi/daa/Makefile.am31
-rw-r--r--src/tspi/daa/big_integer/bi.c237
-rw-r--r--src/tspi/daa/big_integer/bi_gmp.c261
-rw-r--r--src/tspi/daa/big_integer/bi_openssl.c181
-rw-r--r--src/tspi/daa/big_integer/test/Makefile.am9
-rw-r--r--src/tspi/daa/big_integer/test/multi_exp.c29
-rw-r--r--src/tspi/daa/big_integer/test/test.c296
-rw-r--r--src/tspi/daa/daa_anonymityrevocation/csencryption_result.c211
-rw-r--r--src/tspi/daa/daa_debug.c294
-rw-r--r--src/tspi/daa/daa_debug.h66
-rw-r--r--src/tspi/daa/daa_issuer/issue_credential.c787
-rw-r--r--src/tspi/daa/daa_issuer/issuer_init.c142
-rw-r--r--src/tspi/daa/daa_issuer/issuer_setup.c166
-rw-r--r--src/tspi/daa/daa_issuer/key_correctness_proof.c516
-rw-r--r--src/tspi/daa/daa_issuer/key_verification.c147
-rw-r--r--src/tspi/daa/daa_issuer/keypair_generator.c397
-rw-r--r--src/tspi/daa/daa_issuer/prime_gen.c327
-rw-r--r--src/tspi/daa/daa_parameter.c184
-rw-r--r--src/tspi/daa/daa_platform/platform.c2644
-rw-r--r--src/tspi/daa/daa_platform/test.c142
-rw-r--r--src/tspi/daa/daa_platform/test_join.c504
-rw-r--r--src/tspi/daa/daa_structs.c1317
-rw-r--r--src/tspi/daa/daa_verifier/test/Makefile.am7
-rw-r--r--src/tspi/daa/daa_verifier/verifier.c57
-rw-r--r--src/tspi/daa/daa_verifier/verifier_transaction.c873
-rw-r--r--src/tspi/daa/test_sign.c238
-rw-r--r--src/tspi/daa/utils/list.c66
-rw-r--r--src/tspi/gtk/callbacks.c163
-rw-r--r--src/tspi/gtk/callbacks.h58
-rw-r--r--src/tspi/gtk/interface.c299
-rw-r--r--src/tspi/gtk/interface.h30
-rw-r--r--src/tspi/gtk/main.c117
-rw-r--r--src/tspi/gtk/support.c157
-rw-r--r--src/tspi/gtk/support.h81
-rw-r--r--src/tspi/log.c62
-rw-r--r--src/tspi/obj.c297
-rw-r--r--src/tspi/obj_context.c1524
-rw-r--r--src/tspi/obj_daa.c151
-rw-r--r--src/tspi/obj_delfamily.c361
-rw-r--r--src/tspi/obj_encdata.c485
-rw-r--r--src/tspi/obj_hash.c227
-rw-r--r--src/tspi/obj_migdata.c1124
-rw-r--r--src/tspi/obj_nv.c746
-rw-r--r--src/tspi/obj_pcrs.c904
-rw-r--r--src/tspi/obj_policy.c1667
-rw-r--r--src/tspi/obj_rsakey.c2136
-rw-r--r--src/tspi/obj_tpm.c531
-rw-r--r--src/tspi/ps/ps_utils.c57
-rw-r--r--src/tspi/ps/tspps.c1298
-rw-r--r--src/tspi/rpc/hosttable.c182
-rw-r--r--src/tspi/rpc/tcs_api.c3377
-rw-r--r--src/tspi/rpc/tcstp/rpc.c514
-rw-r--r--src/tspi/rpc/tcstp/rpc_admin.c373
-rw-r--r--src/tspi/rpc/tcstp/rpc_aik.c336
-rw-r--r--src/tspi/rpc/tcstp/rpc_audit.c240
-rw-r--r--src/tspi/rpc/tcstp/rpc_auth.c96
-rw-r--r--src/tspi/rpc/tcstp/rpc_bind.c90
-rw-r--r--src/tspi/rpc/tcstp/rpc_caps.c76
-rw-r--r--src/tspi/rpc/tcstp/rpc_caps_tpm.c175
-rw-r--r--src/tspi/rpc/tcstp/rpc_certify.c131
-rw-r--r--src/tspi/rpc/tcstp/rpc_changeauth.c173
-rw-r--r--src/tspi/rpc/tcstp/rpc_cmk.c393
-rw-r--r--src/tspi/rpc/tcstp/rpc_context.c80
-rw-r--r--src/tspi/rpc/tcstp/rpc_counter.c204
-rw-r--r--src/tspi/rpc/tcstp/rpc_daa.c184
-rw-r--r--src/tspi/rpc/tcstp/rpc_delegate.c452
-rw-r--r--src/tspi/rpc/tcstp/rpc_dir.c89
-rw-r--r--src/tspi/rpc/tcstp/rpc_ek.c304
-rw-r--r--src/tspi/rpc/tcstp/rpc_evlog.c231
-rw-r--r--src/tspi/rpc/tcstp/rpc_key.c350
-rw-r--r--src/tspi/rpc/tcstp/rpc_maint.c250
-rw-r--r--src/tspi/rpc/tcstp/rpc_migration.c270
-rw-r--r--src/tspi/rpc/tcstp/rpc_nv.c315
-rw-r--r--src/tspi/rpc/tcstp/rpc_oper.c47
-rw-r--r--src/tspi/rpc/tcstp/rpc_own.c125
-rw-r--r--src/tspi/rpc/tcstp/rpc_pcr_extend.c113
-rw-r--r--src/tspi/rpc/tcstp/rpc_ps.c373
-rw-r--r--src/tspi/rpc/tcstp/rpc_quote.c114
-rw-r--r--src/tspi/rpc/tcstp/rpc_quote2.c149
-rw-r--r--src/tspi/rpc/tcstp/rpc_random.c94
-rw-r--r--src/tspi/rpc/tcstp/rpc_seal.c206
-rw-r--r--src/tspi/rpc/tcstp/rpc_selftest.c155
-rw-r--r--src/tspi/rpc/tcstp/rpc_sign.c93
-rw-r--r--src/tspi/rpc/tcstp/rpc_tick.c172
-rw-r--r--src/tspi/rpc/tcstp/rpc_transport.c368
-rw-r--r--src/tspi/spi_utils.c459
-rw-r--r--src/tspi/ssl_ui.c86
-rw-r--r--src/tspi/tsp_admin.c305
-rw-r--r--src/tspi/tsp_aik.c143
-rw-r--r--src/tspi/tsp_asym.c117
-rw-r--r--src/tspi/tsp_audit.c256
-rwxr-xr-xsrc/tspi/tsp_auth.c1230
-rw-r--r--src/tspi/tsp_bind.c92
-rw-r--r--src/tspi/tsp_caps.c176
-rw-r--r--src/tspi/tsp_caps_tpm.c167
-rw-r--r--src/tspi/tsp_certify.c108
-rw-r--r--src/tspi/tsp_changeauth.c470
-rw-r--r--src/tspi/tsp_context_mem.c258
-rw-r--r--src/tspi/tsp_counter.c57
-rw-r--r--src/tspi/tsp_daa.c207
-rw-r--r--src/tspi/tsp_delegate.c865
-rw-r--r--src/tspi/tsp_dir.c83
-rw-r--r--src/tspi/tsp_ek.c108
-rw-r--r--src/tspi/tsp_get_flags.c67
-rw-r--r--src/tspi/tsp_key.c337
-rw-r--r--src/tspi/tsp_maint.c197
-rw-r--r--src/tspi/tsp_migration.c263
-rw-r--r--src/tspi/tsp_nv.c245
-rw-r--r--src/tspi/tsp_oper.c48
-rw-r--r--src/tspi/tsp_own.c193
-rw-r--r--src/tspi/tsp_pcr.c148
-rw-r--r--src/tspi/tsp_pcr_extend.c112
-rw-r--r--src/tspi/tsp_policy.c123
-rw-r--r--src/tspi/tsp_ps.c347
-rw-r--r--src/tspi/tsp_quote.c114
-rw-r--r--src/tspi/tsp_quote2.c133
-rw-r--r--src/tspi/tsp_random.c89
-rw-r--r--src/tspi/tsp_seal.c254
-rw-r--r--src/tspi/tsp_selftest.c132
-rw-r--r--src/tspi/tsp_sign.c92
-rw-r--r--src/tspi/tsp_tick.c124
-rw-r--r--src/tspi/tsp_transport.c88
-rw-r--r--src/tspi/tspi_admin.c362
-rw-r--r--src/tspi/tspi_aik.c579
-rw-r--r--src/tspi/tspi_asn1.c255
-rw-r--r--src/tspi/tspi_audit.c313
-rw-r--r--src/tspi/tspi_bind.c217
-rw-r--r--src/tspi/tspi_caps.c87
-rw-r--r--src/tspi/tspi_caps_tpm.c356
-rw-r--r--src/tspi/tspi_certify.c164
-rw-r--r--src/tspi/tspi_changeauth.c434
-rw-r--r--src/tspi/tspi_cmk.c475
-rw-r--r--src/tspi/tspi_context.c381
-rw-r--r--src/tspi/tspi_counter.c48
-rw-r--r--src/tspi/tspi_daa.c698
-rw-r--r--src/tspi/tspi_delegate.c470
-rw-r--r--src/tspi/tspi_dir.c105
-rw-r--r--src/tspi/tspi_ek.c438
-rw-r--r--src/tspi/tspi_getset.c1168
-rw-r--r--src/tspi/tspi_hash.c59
-rw-r--r--src/tspi/tspi_key.c706
-rw-r--r--src/tspi/tspi_maint.c269
-rw-r--r--src/tspi/tspi_migration.c400
-rw-r--r--src/tspi/tspi_nv.c527
-rw-r--r--src/tspi/tspi_oper.c52
-rw-r--r--src/tspi/tspi_own.c163
-rw-r--r--src/tspi/tspi_pcr_comp.c56
-rw-r--r--src/tspi/tspi_pcr_comp12.c67
-rw-r--r--src/tspi/tspi_pcr_events.c120
-rw-r--r--src/tspi/tspi_pcr_extend.c158
-rw-r--r--src/tspi/tspi_policy.c115
-rw-r--r--src/tspi/tspi_ps.c581
-rw-r--r--src/tspi/tspi_quote.c217
-rw-r--r--src/tspi/tspi_quote2.c286
-rw-r--r--src/tspi/tspi_random.c74
-rw-r--r--src/tspi/tspi_seal.c327
-rw-r--r--src/tspi/tspi_selftest.c206
-rw-r--r--src/tspi/tspi_sign.c150
-rw-r--r--src/tspi/tspi_tick.c178
-rw-r--r--src/tspi/tspi_transport.c119
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, &current_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, &current_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, &currentTicks,
+ &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(&quoteinfo, 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;
+}