This procedure will transfer an HMAC key created inside TPM-A
to TPM-B
and then to TPM-C
using tpm2_policycommandcode
Basically, and extension of As an end-to-end example, the following will transfer an RSA key generated on TPM-A to TPM-B
To use this, you'll need three VMs.
Step 1 below will transfer a key from A->B
, step 2 is B->C
On VM-B, create parent object used for duplication
tpm2_createprimary -C o -g sha256 -G rsa -c primary.ctx
tpm2_create -C primary.ctx -g sha256 -G rsa -r new_parent.prv \
-u new_parent.pub -a "fixedtpm|fixedparent|restricted|sensitivedataorigin|decrypt|userwithauth"
copy new_parent.pub to A
## just print the public part
tpm2_print -t TPM2B_PUBLIC new_parent.pub
## create a tpm2_policycommandcode with TPM2_CC_Duplicate
tpm2_createprimary -C o -g sha256 -G rsa -c primary.ctx
tpm2_startauthsession -S session.dat
tpm2_policycommandcode -S session.dat -L dpolicy.dat TPM2_CC_Duplicate
tpm2_flushcontext session.dat
rm session.dat
## create the hmac key on the tpm with the policy
tpm2_create -C primary.ctx -g sha256 -G hmac -r key.prv -u key.pub \
-L dpolicy.dat -a "sensitivedataorigin|userwithauth|sign"
## load and print the hmac key details
tpm2_load -C primary.ctx -r key.prv -u key.pub -c key.ctx
tpm2_readpublic -c key.ctx -n dupkey.name
## now hmac some data
## (the output for you will be different)
export plain="foo"
echo -n $plain | tpm2_hmac -g sha256 -c key.ctx | xxd -p -c 256
5bc1d93ea8b7a180877eeb754bf5f3bd84e94aa397b8ab5284dbd5dc823ff7c7
## now begin the duplication using the new_parent and the same policy
tpm2_readpublic -c key.ctx -o dup.pub
tpm2_startauthsession --policy-session -S session.dat
tpm2_policycommandcode -S session.dat -L dpolicy.dat TPM2_CC_Duplicate
tpm2_loadexternal -C o -u new_parent.pub -c new_parent.ctx -n dst_n.name
tpm2_duplicate -C new_parent.ctx -c key.ctx -G null -p "session:session.dat" -r dup.dup -s dup.seed
copy dup.dup dup.seed dup.pub to B
## load the parent key used for duplication
tpm2_flushcontext --transient-object
tpm2_load -C primary.ctx -u new_parent.pub -r new_parent.prv -c new_parent.ctx
## set the duplicate policy
tpm2_startauthsession --policy-session -S session.dat
tpm2_policycommandcode -S session.dat -L dpolicy.dat TPM2_CC_Duplicate
## import and load the duplicated key
tpm2_import -C new_parent.ctx -u dup.pub -i dup.dup -r dup.prv -s dup.seed -L dpolicy.dat
tpm2_flushcontext --transient-object
tpm2_load -C new_parent.ctx -u dup.pub -r dup.prv -c dup.ctx
## now run the hmac
## (you'll see the same output as on A)
export plain="foo"
echo -n $plain | tpm2_hmac -g sha256 -c dup.ctx | xxd -p -c 256
5bc1d93ea8b7a180877eeb754bf5f3bd84e94aa397b8ab5284dbd5dc823ff7c7
Repeate the same prodedure between B and C using the key loaded in the previous step
## create a parent for the transfer
tpm2_createprimary -C o -g sha256 -G rsa -c primary_2.ctx
tpm2_create -C primary_2.ctx -g sha256 -G rsa -r new_parent_2.prv \
-u new_parent_2.pub -a "fixedtpm|fixedparent|restricted|sensitivedataorigin|decrypt|userwithauth"
_ copy new_parent_2.pub to B_
## just to test, load the _original_ key sent a->b and run an hmac again
## this step isn't necessary but helps as a sanity check
tpm2_load -C new_parent.ctx -u dup.pub -r dup.prv -c dup.ctx
export plain="foo"
echo -n $plain | tpm2_hmac -g sha256 -c dup.ctx | xxd -p -c 256
## print the public part of the parent from C
tpm2_print -t TPM2B_PUBLIC new_parent_2.pub
## start a duplicate session
tpm2_startauthsession -S session_2.dat --policy-session
tpm2_policycommandcode -S session_2.dat -L dpolicy_2.dat TPM2_CC_Duplicate
tpm2_flushcontext session_2.dat
rm session_2.dat
## again load the key sent from A
tpm2_load -C new_parent.ctx -u dup.pub -r dup.prv -c dup.ctx
## fulfill the policy for duplication
## load the parent from C
tpm2_startauthsession --policy-session -S session.dat
tpm2_policycommandcode -S session.dat -L dpolicy.dat TPM2_CC_Duplicate
tpm2_loadexternal -C o -u new_parent_2.pub -c new_parent_2.ctx
## duplicate
tpm2_duplicate -C new_parent_2.ctx -c dup.ctx -G null \
-p "session:session.dat" -r dup_2.dup -s dup_2.seed
cp dup.pub dup_2.pub
copy dup_2.dup dup_2.seed dup_2.pub to C
## load the original parent from C
tpm2_flushcontext --transient-object
tpm2_load -C primary_2.ctx -u new_parent_2.pub -r new_parent_2.prv -c new_parent_2.ctx
## start the policy
tpm2_startauthsession --policy-session -S session.dat
tpm2_policycommandcode -S session.dat -L dpolicy.dat TPM2_CC_Duplicate
## import the duplicated key
tpm2_import -C new_parent_2.ctx -u dup_2.pub -i dup_2.dup -r dup_2.prv -s dup_2.seed -L dpolicy.dat
tpm2_flushcontext --transient-object
tpm2_load -C new_parent_2.ctx -u dup_2.pub -r dup_2.prv -c dup_2.ctx
## test with hmac
## you'll see the same hmac output
export plain="foo"
echo -n $plain | tpm2_hmac -g sha256 -c dup_2.ctx | xxd -p -c 256
5bc1d93ea8b7a180877eeb754bf5f3bd84e94aa397b8ab5284dbd5dc823ff7c7