The following transfer a key from TPM-A to TPM-B and demonstrates policies that prevent further duplication to TPM-C
ref:
First start three swtpms to simulat A, B, C:
rm -rf myvtpm && mkdir myvtpm
/usr/share/swtpm/swtpm-create-user-config-files
swtpm_setup --tpmstate myvtpm --tpm2 --create-ek-cert
swtpm socket --tpmstate dir=myvtpm --tpm2 --server type=tcp,port=2321 --ctrl type=tcp,port=2322 --flags not-need-init,startup-clear --log level=2
export TPM2TOOLS_TCTI="swtpm:port=2321"
rm -rf myvtpm2 && mkdir myvtpm2
/usr/share/swtpm/swtpm-create-user-config-files
swtpm_setup --tpmstate myvtpm2 --tpm2 --create-ek-cert
swtpm socket --tpmstate dir=myvtpm2 --tpm2 --server type=tcp,port=2341 --ctrl type=tcp,port=2342 --flags not-need-init,startup-clear --log level=2
export TPM2TOOLS_TCTI="swtpm:port=2341"
rm -rf myvtpm3 && mkdir myvtpm3
/usr/share/swtpm/swtpm-create-user-config-files
swtpm_setup --tpmstate myvtpm3 --tpm2 --create-ek-cert
swtpm socket --tpmstate dir=myvtpm3 --tpm2 --server type=tcp,port=2351 --ctrl type=tcp,port=2352 --flags not-need-init,startup-clear --log level=2
export TPM2TOOLS_TCTI="swtpm:port=2351"on tpmb, create the new parent
export TPM2TOOLS_TCTI="swtpm:port=2341"
tpm2_flushcontext -t
tpm2_createprimary -C o -g sha256 -G rsa -c primaryB.ctx
tpm2_create -C primaryB.ctx -g sha256 -G rsa \
-r new_parentB.prv -u new_parentB.pub \
-a "restricted|sensitivedataorigin|decrypt|userwithauth"
tpm2_flushcontext -ton tpm a create an rsa key and duplicate that to tpm-B's parent
export TPM2TOOLS_TCTI="swtpm:port=2321"
tpm2_createprimary -C o -g sha256 -G rsa -c primaryA.ctx
tpm2_startauthsession -S sessionA.dat
tpm2_policyauthvalue -S sessionA.dat -L policyA_auth.dat
tpm2_flushcontext sessionA.dat
rm sessionA.dat
tpm2_loadexternal -C o -u new_parentB.pub -c new_parentB.ctx -n dst_n.name
tpm2_startauthsession -S sessionA.dat
tpm2_policyduplicationselect -S sessionA.dat -N dst_n.name -L policyA_dupselect.dat
tpm2_flushcontext sessionA.dat
rm sessionA.dat
tpm2_startauthsession -S sessionA.ctx
tpm2_policyor -S sessionA.ctx -L policyA_or.dat sha256:policyA_auth.dat,policyA_dupselect.dat
tpm2_flushcontext sessionA.ctx
tpm2_flushcontext -t
tpm2_create -C primaryA.ctx -G rsa -g sha256 -r key.prv -u key.pub -L policyA_or.dat -a "sensitivedataorigin|decrypt|sign" -p bar
tpm2_flushcontext -t
tpm2_load -C primaryA.ctx -r key.prv -u key.pub -c key.ctx -n key.name
tpm2_readpublic -c key.ctx -o dup.pub
tpm2_flushcontext -t
tpm2_startauthsession -S sessionA.dat --policy-session
tpm2_policyauthvalue -S sessionA.dat -L policyA_auth.dat
tpm2_flushcontext sessionA.dat
rm sessionA.dat
tpm2_startauthsession -S sessionA.dat --policy-session
tpm2_policyduplicationselect -S sessionA.dat -N dst_n.name -L policyA_dupselect.dat
tpm2_flushcontext sessionA.dat
rm sessionA.dat
tpm2_startauthsession -S sessionA.dat --policy-session
tpm2_policyauthvalue -S sessionA.dat -L policyA_.dat
tpm2_policyor -S sessionA.dat -L policyA_or.dat sha256:policyA_auth.dat,policyA_dupselect.dat
tpm2_flushcontext -t
echo "meet me at.." >file.txt
tpm2_sign -c key.ctx -g sha256 -f plain -p"session:sessionA.dat+bar" -o sig.rss file.txt
tpm2_flushcontext -t
tpm2_loadexternal -C o -u new_parentB.pub -c new_parentB.ctx -n dst_n.name
tpm2_flushcontext -t
tpm2_startauthsession -S sessionA.dat --policy-session
tpm2_policyduplicationselect -S sessionA.dat -N dst_n.name -n key.name -L policyA_dupselect.dat
tpm2_policyor -S sessionA.dat -L policyA_or.dat sha256:policyA_auth.dat,policyA_dupselect.dat
tpm2_flushcontext -t
tpm2_duplicate -C new_parentB.ctx -c key.ctx -G null -p "session:sessionA.dat" -r dup.dpriv -s dup.seed
tpm2_flushcontext -tnow on B, import and use the imported key to sign
export TPM2TOOLS_TCTI="swtpm:port=2341"
tpm2_flushcontext --transient-object
tpm2_load -C primaryB.ctx -u new_parentB.pub -r new_parentB.prv -c new_parentB.ctx
tpm2_import -C new_parentB.ctx -u dup.pub -i dup.dpriv -r dup.prv -s dup.seed
tpm2_flushcontext -t
tpm2_load -C new_parentB.ctx -u dup.pub -r dup.prv -c dup.ctx
tpm2_readpublic -c dup.ctx -o dup.pub
tpm2_flushcontext -t
tpm2_startauthsession -S sessionB.dat --policy-session
tpm2_policyauthvalue -S sessionB.dat -L policyB_auth.dat
tpm2_flushcontext sessionB.dat
rm sessionB.dat
tpm2_startauthsession -S sessionB.dat --policy-session
tpm2_policyduplicationselect -S sessionB.dat -N dst_n.name -L policyB_dupselect.dat
tpm2_flushcontext sessionB.dat
rm sessionB.dat
tpm2_startauthsession -S sessionB.dat --policy-session
tpm2_policyauthvalue -S sessionB.dat -L policyB_auth.dat
tpm2_policyor -S sessionB.dat -L policyB_or.dat sha256:policyB_auth.dat,policyB_dupselect.dat
tpm2_flushcontext -t
echo "meet me at.." >file.txt
tpm2_sign -c dup.ctx -g sha256 -f plain -o signB.raw file.txt -p "session:sessionB.dat+bar"
tpm2_flushcontext sessionB.dat
rm sessionB.dat
tpm2_flushcontext -tnow create a parent on tpm-c
export TPM2TOOLS_TCTI="swtpm:port=2351"
tpm2_flushcontext -t
tpm2_createprimary -C o -g sha256 -G rsa -c primaryC.ctx
tpm2_create -C primaryC.ctx -g sha256 -G rsa \
-r new_parentC.prv -u new_parentC.pub \
-a "restricted|sensitivedataorigin|decrypt|userwithauth"
tpm2_flushcontext -ttry to duplicate to tpm-c, thi'll fail
export TPM2TOOLS_TCTI="swtpm:port=2341"
tpm2_loadexternal -C o -u new_parentC.pub -c new_parentC.ctx -n dst_c.name
tpm2_flushcontext --transient-object
tpm2_load -C new_parentB.ctx -u dup.pub -r dup.prv -c dup.ctx
tpm2_startauthsession -S sessionB.dat --policy-session
tpm2_policyauthvalue -S sessionB.dat -L policyC_auth.dat
tpm2_flushcontext sessionB.dat
rm sessionB.dat
tpm2_startauthsession -S sessionB.dat --policy-session
tpm2_policyduplicationselect -S sessionB.dat -N dst_c.name -L policyC_dupselect.dat
tpm2_flushcontext sessionB.dat
rm sessionB.dat
tpm2_startauthsession -S sessionB.dat --policy-session
tpm2_policyauthvalue -S sessionB.dat -L policyC_auth.dat
tpm2_policyor -S sessionB.dat -L policyC_or.dat sha256:policyC_auth.dat,policyC_dupselect.dat
tpm2_startauthsession -S sessionC.dat --policy-session
tpm2_policyduplicationselect -S sessionC.dat -N dst_c.name -L policyC_dupselect.dat
tpm2_policyor -S sessionC.dat -L policyC_or.dat sha256:policyC_auth.dat,policyC_dupselect.dat
tpm2_flushcontext -t
tpm2_duplicate -C new_parentC.ctx -c dup.ctx -G null -p "session:sessionC.dat+bar" -r dupC.dpriv -s dupC.seed
tpm2_flushcontext -t
you'll see:
WARNING:esys:src/tss2-esys/api/Esys_Duplicate.c:357:Esys_Duplicate_Finish() Received TPM Error
ERROR:esys:src/tss2-esys/api/Esys_Duplicate.c:119:Esys_Duplicate() Esys Finish ErrorCode (0x0000099d)
ERROR: Esys_Duplicate(0x99D) - tpm:session(1):a policy check failed
ERROR: Unable to run tpm2_duplicate