Skip to content

Instantly share code, notes, and snippets.

@salrashid123
Created May 9, 2024 14:40
Show Gist options
  • Save salrashid123/13166ff8d579d55436a128087d5b43c7 to your computer and use it in GitHub Desktop.
Save salrashid123/13166ff8d579d55436a128087d5b43c7 to your computer and use it in GitHub Desktop.
Duplicate and Transfer an encoded key from TPM-A -> TPM-B -> TPM-C using tpm2_policycommandcode

Chained duplication from A -> B -> C tpm2_policycommandcode

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

1. Transfer A-->B

B

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

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

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

Transfer B-->C

Repeate the same prodedure between B and C using the key loaded in the previous step

C

## 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_

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

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment