tpm2-tools
tpm2-tools copied to clipboard
tpm2_policyauthorize: using a “Wildcard Policy” to unseal a key
I tried to use the code from Nicolas Oliver to create a tpm-based key which has a “Wildcard Policy” i.e. an Authorized Policiy to allow using the key only with specified PCR values. Support for this is provided thorough the tpm2_policyauthorize command.
I just adapted the code from https://github.com/latchset/clevis/issues/121
Instead of sealing a file (in the code Nicolas it is file secret.txt I tried to use a tpm-stored key within the “normal” owner hierarchy i.e. a subkey of the primary key. When I try to unseal the key at the end of the code I get the following error:
/home/user# tpm2_unseal
--object-context 0x81000005
--auth session:session1.ctx
WARNING:esys:src/tss2-esys/api/Esys_Unseal.c:295:Esys_Unseal_Finish() Received TPM Error
ERROR:esys:src/tss2-esys/api/Esys_Unseal.c:98:Esys_Unseal() Esys Finish ErrorCode (0x0000018a)
ERROR: Esys_Unseal(0x18A) - tpm:handle(1):the type of the value is not appropriate for the use
Can’t we use tpm2_policyauthorize directly on tpm-keys in tpm2-tools? (or maybe it is written in the spec where I haven’t read all the details.)
I also tried in a second attempt to create a subkey (wrapped key) of a parent key and using the authorization value of the parent key with option --parent-auth when calling tpm2_create
Here is the complete code:
tpm2_startup --clear
Create a PCR policy |
tpm2_startauthsession --session session.ctx
tpm2_policypcr
--session session.ctx
--pcr-list sha256:0,1
--policy pcr.policy
tpm2_flushcontext session.ctx
rm -f session.ctx
Generate public/private key pair for signing
tpm2_createprimary
--hierarchy o
--hash-algorithm sha256
--key-algorithm rsa
--key-context primary.ctx
tpm2_create
--parent-context primary.ctx
--hash-algorithm sha256
--public sigkey.obj.pub
--private sigkey.obj.priv
-p str:pwd
Loading the public key in TPM
tpm2_load
--parent-context primary.ctx
--public sigkey.obj.pub
--private sigkey.obj.priv
--name sigkey.obj.name
--key-context sigkey.obj.ctx
Flush transient objects
tpm2_flushcontext --transient
Create an authorized policy
tpm2_startauthsession --session session.ctx
tpm2_policyauthorize
--session session.ctx
--policy authorized.policy
--name sigkey.obj.name
--input pcr.policy
tpm2_create
--parent-context primary.ctx
--hash-algorithm sha256
--public key.obj.pub
--private key.obj.priv
--policy authorized.policy
tpm2_load
--parent-context primary.ctx
--public key.obj.pub
--private key.obj.priv
--name key.obj.name
--key-context key.obj.ctx
Persist the TPM Object
tpm2_evictcontrol
--hierarchy o
--object-context key.obj.ctx
0x81000005
Flush transient objects
tpm2_flushcontext --transient
Sign the PCR policy
tpm2_sign -c sigkey.obj.ctx -g sha256 -p str:pwd
-o pcr.policy.signature pcr.policy
tpm2_load
--parent-context primary.ctx
--public sigkey.obj.pub
--private sigkey.obj.priv
--name sigkey.obj.name
--key-context sigkey.obj.ctx
Verify the signature
tpm2_verifysignature
--ticket verification.tkt
--key-context sigkey.obj.ctx
--hash-algorithm sha256
--message pcr.policy
--signature pcr.policy.signature \
Flush transient objects
tpm2_flushcontext --transient
Unseal the TPM object using the Authorized PCR Policy
tpm2_startauthsession
--policy-session
--session session1.ctx
tpm2_policypcr
--session session1.ctx
--pcr-list sha256:0,1
tpm2_policyauthorize
--session session1.ctx
--policy authorized.policy
--input pcr.policy
--name sigkey.obj.name
--ticket verification.tkt
tpm2_unseal
--object-context 0x81000005
--auth session:session1.ctx
You did not specify the data to seal (-i) when you executed tpm2_create
for key.obj.priv
So no keyed hash object is created and the error 0x18a
will be produced.
P.S. You do not need the --policy
parameter for the first execution of tpm2_policyauthorize
Thank you very much Jürgen Repp. What you write as a solution is exactly what I don't want to do: tpm2_create can be used in 2 different variants. According to the man-page: „tpm2_create(1) - Create a child object. The object can either be a key or a sealing object…“ I would like to have the first variant of tpm2_create, i.e. the child object should be a key and not a sealing object. I don't want to use tpm2_create with option "-i", i.e. I don't want to seal data, but I want to create a "child key" i.e. a "wrapped" key that is generated by the TPM random number generator and is encrypted ("wrapped") with the parent key and stored exclusively in the TPM. The key should never leave the TPM. The use of this key should be protected by policyauthorize. Is it not possible to do this with the TPM?
I also tried to put the policy to the parent key like in the following code snippet. The policy was created with tpm2_policyauthorize beforehand; like in the code in my first comment above; not shown here.
tpm2_createprimary
--hierarchy o
--hash-algorithm sha256
--key-algorithm rsa
--key-context primary.ctx
tpm2_create
--parent-context primary.ctx
--hash-algorithm sha256
--public key.obj.pub
--private key.obj.priv
--policy authorized.policy
tpm2_load
--parent-context primary.ctx
--public key.obj.pub
--private key.obj.priv
--name key.obj.name
--key-context key.obj.ctx
# create child key using the policy for the parent key (with option --parent-auth)
tpm2_create
--parent-context key.obj.ctx
--hash-algorithm sha256
--public key1.obj.pub
--private key1.obj.priv
--parent-auth session:session.ctx
Here I get this error:
WARNING:esys:src/tss2-esys/api/Esys_Create.c:398:Esys_Create_Finish() Received TPM Error ERROR:esys:src/tss2-esys/api/Esys_Create.c:134:Esys_Create() Esys Finish ErrorCode (0x0000018a) ERROR: Esys_Create(0x18A) - tpm:handle(1):the type of the value is not appropriate for the use ERROR: Unable to run tpm2_create
Your example worked if -i was used. So If -i is not used a normal key will be created. Actions with this key will be protected by the policy you provided. As i understood you, that was the goal. But unseal was not an appropriate action.
Thank you @Jürgen Repp @JuergenReppSIT
What you write as a solution for me is exactly what I don't want to do: I don't want to seal external data, but I want the TPM to generate a key that exists exclusively in the TPM (i.e. a "wrapped" key).
Here some Background-Information: in IMA/EVM you can use a so-called „trusted key“ for EVM. The big advantage of this is that the „trusted key“ is only visible in the kernel and is protected by a TPM key. The trusted key is never visible in Userland. This is exactly the reason why I don't want to seal external data (which would then be visible in userland when unsealing), but I want to use a TPM key directly for IMA/EVM. However, BIOS updates should be possible, so I have to use tpm2_policyauthorize for the TPM key and that doesn't seem to work.
So I would like to do something like this:
keyctl add trusted kmk-trusted "new 32 keyhandle=0x81000001" @s
where 0x81000001 is a key generated by the TPM that has never left the tpm and will never leave it. see chapter „Setting up the keys (for cryptographic hashing)“ in https://wiki.gentoo.org/wiki/Extended_Verification_Module
further links to IMA/EVM: (https://sourceforge.net/p/linux-ima/wiki/Home/) https://sourceforge.net/p/linux-ima/mailman/linux-ima-user/thread/[email protected]/
Trusted keys are symmetric keys generated by the kernel which are sealed by a TPM key as parent. In your example 0x81000001. I think the pcr policy for the sealed object has to be defined by using the keyctl command.
Your second example did not work because the parent for key (key1.obj...) needs the attribute decrypt and restricted. e.g
--attributes "fixedtpm|fixedparent|sensitivedataorigin|decrypt|restricted"