tpm2-pkcs11 icon indicating copy to clipboard operation
tpm2-pkcs11 copied to clipboard

Not able to do activate credential on pkcs11 key objects added using tpm2_ptool while tpm2_create objects works file.

Open pchand20 opened this issue 6 months ago • 7 comments

I am not able to do activate credential on pkcs11 key object added using tpm2_ptool while tpm2_create objects works file.

here is sequence:
tpm2_ptool init is done on primary context. and after that following keys are added using tpm2_ptool. but I am not able to do activate credentials same way as done by tpm2_create objects.

Create a primary key

$tpm2_createprimary -c primary.ctx $tpm2_evictcontrol -c primary.ctx 0x81000001 $ tpm2_ptool init --primary-handle=0x81000001 –path=/path/to/store

Add storage keys: tpm2_ptool addtoken --pid=1 --sopin=<> --userpin=<> --label=label --path $TPM2_PKCS11_STORE tpm2_ptool addkey --label=label --userpin=<> --algorithm=rsa2048 --key-label=$CKA_LABEL --path $TPM2_PKCS11_STORE

tpm2_ptool objmod --key 2399141890 --id=2 --path=$TPM2_PKCS11_STORE | cut -d' ' -f2-2 | xxd -r -p -c1024 > pkcs11key.pub tpm2_loadexternal -Cn -u pkcs11key.pub -c pkcs11key.ctx tpm2_readpublic -c pkcs11keykey.ctx -n pkcs11keykey.name

make credential works fine but activate credentials give following error. ERROR: Incorrect handle value, got: "pkcs11keykey.ctx", expected expected [o|p|e|n|l] or a handle number ERROR: Unable to read as BIO file ERROR: Unable to fetch public/private portions of TSS PRIVKEY ERROR: Cannot make sense of object context "pkcs11keykey.ctx" ERROR: Unable to run tpm2_readpublic

while makecredentail and activate credential method do work if I add keys by following tpm2_tools.

tpm2_create -C primary.ctx -u key.pub -r key.priv -a 'fixedtpm|fixedparent|restricted|userwithauth|sensitivedataorigin|decrypt' tpm2_load -C primary.ctx -u key.pub -r key.priv -c key.ctx tpm2_readpublic -c key.ctx -n key.name

seems the key object is not compatible with pytss , any idea?

pchand20 avatar Dec 11 '23 15:12 pchand20

I have no idea how you're calling tpm2_makcredential, so lets start with a working example:

tpm2 createprimary -c primary.ctx
tpm2 readpublic -c primary.ctx -o primary.pub -n key.name

cp primary.ctx key.ctx
# uncomment this to use a seperate key it will just clobber key.ctx
#tpm2 create -C primary.ctx -u key.pub -r key.priv
#tpm2 load -C primary.ctx -u key.pub -r key.priv -c key.ctx
#tpm2 readpublic -c key.ctx -n key.name

# Client sends data to server needed for makecredential.

# SERVER: The server side creates a credential, this could be an HMAC key. This is the same as makecred in tpm2-pytss
echo -n "mycred" > mycred.bin
tpm2 makecredential --tcti=none -u primary.pub -s mycred.bin  -n $(xxd -p -c256 key.name) -o mkcred.bin

# CLIENT: activates the credential, which is just getting it back out for use
tpm2 activatecredential -Cprimary.ctx -c key.ctx -i mkcred.bin -o actcred.bin

# gotten cred should match expected
cmp actcred.bin mycred.bin

echo "success"
exit 0

tpm2_activatecredential requires private key material to made available, so a context file to apublic only object loaded through tpm2_loadexternal wont work. You need to get all the details and load the obbject using tpm2_load. The best way to get these details is using tpm2_ptool export commandlet. You need both the parent and child loaded.

billatarm avatar Dec 11 '23 19:12 billatarm

Hi Bill, Thanks for your response. could you please help to get a working example for tpm2_ptool ?

pchand20 avatar Dec 11 '23 20:12 pchand20

# set up a persistent SRK at the TCG defined address
tpm2 createprimary -c primary.ctx
tpm2 evictcontrol -c primary.ctx 0x81000001

# init the store
./tools/tpm2_ptool init --primary-handle=0x81000001

# add a token to the primary key
tpm2_ptool addtoken --pid=1 --sopin=mysopin --userpin=myuserpin --label=mytoken

# add some keys
tpm2_ptool addkey --label=mytoken --userpin=myuserpin --algorithm=rsa2048 --key-label=key1
tpm2_ptool addkey --label=mytoken --userpin=myuserpin --algorithm=rsa2048 --key-label=key2

# export them
./tools/tpm2_ptool export --label=mytoken --key-label=key1 --userpin=myuserpin
object-auth: c626c183fb607723971e09c10e22b298
primary-object:
  auth: ''
  hierarchy: owner
  is_transient: false

# this creates 3 files: key1.tr (parent key) key1.pub and key2.priv (tpm blobs)
# You can print the key1.tr to get the parent details as well:
tpm2 print --type ESYS_TR key1.tr
tpm-handle: 0x81000001
name: 000bd090c5a432c760b513bd5006eea290124edc5bdce57f2a75795a12fcecc0c00c

# load the key
../tpm2-tools/tools/tpm2 load -Ckey1.tr -u key1.pub -r key1.priv -c key1.ctx
name: 0x000bf7cef3c177cceebd21346feec6fd791a0ebd49f87a17ac1d37ae6b82992dafe9

# now you have a context that can be used in commands. However the symmetric details for basic
# keys are missing, so it can't be used in makecred commands and would need to be supported.
# ie addkey or however the key is added to the pkcs11 store, it needs its symmetric details set IIUC.

billatarm avatar Dec 11 '23 21:12 billatarm

Hi Bill, about following comment's.

now you have a context that can be used in commands. However the symmetric details for basic

keys are missing, so it can't be used in makecred commands and would need to be supported.

ie addkey or however the key is added to the pkcs11 store, it needs its symmetric details set IIUC._

does this support need to be added in makecredential or in tpm2_ptool ?

pchand20 avatar Dec 12 '23 16:12 pchand20

TL;DR: The key used to encrypt the credential must be a parent key(ie attribute restricted), the other key can be anything. The parent key can be used for both inputs.

So if we look at makecredential python code function signature:


def make_credential(
    public: TPM2B_PUBLIC, credential: bytes, name: TPM2B_NAME
) -> Tuple[TPM2B_ID_OBJECT, TPM2B_ENCRYPTED_SECRET]:
    """Encrypts credential for use with activate_credential

the credential TPM2B_PUBLIC argument needs to have the symmetric setting set. This key must be a restricted key (ie a parent key) as created below. primarykeys are also parent keys have the symmetric settings set in the object.

./tpm2 create -C primary.ctx -Grsa2048:null:aes128cfb -a'restricted|userwithauth|decrypt|sensitivedataorigin' -c key.ctx

truncated YAML output for clarity

sym-alg:
  value: aes
  raw: 0x6
sym-mode:
  value: cfb
  raw: 0x43
sym-keybits: 128

A normal key won't have the symmetric portion set.

williamcroberts avatar Dec 12 '23 17:12 williamcroberts

got it now, wondering if this is limitation by spec or by implementation. ? if its implementation gap, we can add that support. I think it will be good add to have all derived key have makecredential and activate credential available to have per part binding with TPM.

pchand20 avatar Dec 12 '23 17:12 pchand20

got it now, wondering if this is limitation by spec or by implementation. ? if its implementation gap, we can add that support. I think it will be good add to have all derived key have makecredential and activate credential available to have per part binding with TPM.

TL;DR it's so arbitrary TPM keys are not used as parents possible compromising the object protections of the child.

Its a spec thing. It's required as a way to preserve the object protections scheme. Essentially is you use the public portion of an object to protect a child key (ie tpm2-pytss wrap command), you don't want any TPM key to be able to decrypt it. If that TPM key is useable by anyone (like the TCG compliant SRK at 0x81000001), then someone could decrypt the child key outside of the TPM. Per the spec, "When restricted is CLEAR, there are no restrictions on the use of the private portion of the key for decryption and the key may be used to decrypt and return any structure encrypted by the public portion of the key. ".

williamcroberts avatar Dec 12 '23 20:12 williamcroberts