Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tpm2_policyauthorize: using a “Wildcard Policy” to unseal a key #3319

Open
arminfhv opened this issue Dec 15, 2023 · 6 comments
Open

tpm2_policyauthorize: using a “Wildcard Policy” to unseal a key #3319

arminfhv opened this issue Dec 15, 2023 · 6 comments

Comments

@arminfhv
Copy link

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 latchset/clevis#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

@JuergenReppSIT
Copy link
Member

JuergenReppSIT commented Dec 15, 2023

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

@arminfhv
Copy link
Author

arminfhv commented Dec 17, 2023

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?

@arminfhv
Copy link
Author

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

@JuergenReppSIT
Copy link
Member

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.

@arminfhv
Copy link
Author

arminfhv commented Dec 20, 2023

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/1484644507.19478.45.camel@intel.com/

@JuergenReppSIT
Copy link
Member

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"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants