Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save salrashid123/8cf62917392c3a05b4a750ce3cfe4c6a to your computer and use it in GitHub Desktop.
Save salrashid123/8cf62917392c3a05b4a750ce3cfe4c6a to your computer and use it in GitHub Desktop.
Prevent Chained duplication from TPM-A -> TPM-B -> TPM-C using tpm2_policyduplicationselect

Prevent Chained duplication from A -> B -> C using tpm2_policyduplicationselect

This procedure will transfer an HMAC key created inside TPM-A to TPM-B but prevent TPM-B to transfer it to TPM-C.

Basically, and extension of As an end-to-end example, the following will transfer an RSA key generated on TPM-A to TPM-B but using tpm2_policyduplicationselect tp prevent further duplication

Step 1 below will transfer a key from A->B, step 2 attempts B->C but is prevented duplication on B by policy


1. Transfer A->B

B

## on B, first create a parent object
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

## read the paren public part, load it and export its "name"
tpm2_print -t TPM2B_PUBLIC  new_parent.pub
tpm2_loadexternal -C o -u new_parent.pub -c new_parent.ctx -n dst_n.name

## create a primary object and a policy that that restricts duplicatoin to just `dst_n.name`
tpm2_createprimary -C o -g sha256 -G rsa -c primary.ctx
tpm2_startauthsession -S session.dat
tpm2_policyduplicationselect -S session.dat  -N dst_n.name -L dpolicy.dat 
tpm2_flushcontext session.dat
rm session.dat

## create an hmac key with that policy
tpm2_create -C primary.ctx -g sha256 -G hmac -r key.prv -u key.pub  -L dpolicy.dat -a "sensitivedataorigin|userwithauth|sign"
tpm2_load -C primary.ctx -r key.prv -u key.pub -c key.ctx

## create a test hmac 
export plain="foo"
echo -n $plain | tpm2_hmac -g sha256 -c key.ctx | xxd -p -c 256
   42a1fad918fa0e4cbea94d759da89ccdfac5a640672d0170f4930cafe14d179c

### print the key  context and export the public part
tpm2_readpublic -c key.ctx -o dup.pub

## now start an auth session 
## bind the duplicate to the destination "name"
tpm2_startauthsession --policy-session -S session.dat
tpm2_readpublic -c key.ctx -n dupkey.name
tpm2_policyduplicationselect -S session.dat  -N dst_n.name -L dpolicy.dat  -n dupkey.name

## now duplicate 
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

## reload the parent used for the transfer
tpm2_flushcontext --transient-object
tpm2_load -C primary.ctx -u new_parent.pub -r new_parent.prv -c new_parent.ctx

## just import the duplicated key
tpm2_import -C new_parent.ctx -u dup.pub -i dup.dup  -r dup.prv -s dup.seed
tpm2_load -C new_parent.ctx -u dup.pub -r dup.prv -c dup.ctx

## test hmac 
## this will be the same as on A
export plain="foo"
echo -n $plain | tpm2_hmac -g sha256 -c dup.ctx | xxd -p -c 256
   42a1fad918fa0e4cbea94d759da89ccdfac5a640672d0170f4930cafe14d179c

tpm2_print -t TPM2B_PUBLIC  dup.pub 

Transfer B-->C

Now try to tranfer the same key from B to C

C

## create a parent on C used 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 as a sanity check load the **original** hmac key and check it
## remember this key was transfered from A->B using new_parent (new_parent_2 is from B->C)
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


## load load new_parent_2 (which is the key from C)
tpm2_loadexternal -C o -u new_parent_2.pub -c new_parent_2.ctx -n dst_n.name
tpm2_startauthsession --policy-session -S session_2.dat
tpm2_readpublic -c dup.ctx -n dupkey.name

## set the policy duplicate against the "name" from C
tpm2_policyduplicationselect -S session_2.dat  -N dst_n.name -L dpolicy_2.dat  -n dupkey.name

## duplication will fail by policy 
### since the key is restricted to a parent
tpm2_duplicate -C new_parent_2.ctx -c dup.ctx -G null  -p "session:session_2.dat" -r dup_2.dup -s dup_2.seed


      WARNING:esys:src/tss2-esys/api/Esys_Duplicate.c:354:Esys_Duplicate_Finish() Received TPM Error 
      ERROR:esys:src/tss2-esys/api/Esys_Duplicate.c:116:Esys_Duplicate() Esys Finish ErrorCode (0x0000099d) 
      ERROR: Esys_Duplicate(0x99D) - tpm:session(1):a policy check failed
      ERROR: Unable to run tpm2_duplicate
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment