On Tue, 2019-12-03 at 02:11 +0000, Zhao, Shirley wrote: > Thanks so much for you feedback, James. > And glad to hear that the API will be made more friendly. > > But I have a little confused about the call stack. > From the document, https://github.com/torvalds/linux/blob/master/Docu > mentation/security/keys/trusted-encrypted.rst and > https://github.com/zfsonlinux/dracut/tree/master/modules.d/97masterke > y, the trusted key is a random number and generated by TPM2.0 and > sealed with TPM2.0 2048 RSA key. Well, um, that document seems to be based on TPM 1.2 ... a lot of what it says isn't quite true for TPM 2.0. For instance all TPM 2.0 primary keys come with a symmetric component, so the sealed data in TPM 2.0 is actually symmetrically encrypted to a primary key. > The 2048 RSA key is generated by tpm2_createprimary, and it can be > got by the TPM2.0 handle, just the "keyhandle" used in the following > keyctl command. > $ keyctl add trusted kmk "new 32 keyhandle=0x81000001 hash=sha256 > policydigest=`cat pcr7.policy`" @u The problem TPM 2.0 has is that most of them can't generate prime numbers very fast, so even through the kernel could generate the RSA primary, it would usually take far too long, so if you want to use a RSA primary you have to pre-generate one and place it in NV storage; the TCG recommends doing this at handle 81000001, which is what you have above. However, the more modern way is to derive an elliptic curve key primary key every time ... EC keys can be generated by most TPMs in 10s of milliseconds, so the primary doesn't need to be present in NVRAM. THe kernel should be using the EC primary method for the parent. The only exception is when the key has an intermediate parent, and then it can be simply loaded from a file. > If reboot, to re-load the trusted key back to keyring, just call > tpm2_unseal is enough, don't need to call tpm2_load to load the > TPM2.0 2048 RSA key. > If the trusted key is also protected by policy, then the policy will > be checked during tpm2_unseal. > > After check the source code, the call stack is mostly like: > SYSCALL_DEFINE5(add_key,...) --> key_create_or_update() --> > __key_instantiate_and_link() --> trusted_instantiate() --> > tpm2_unseal_trusted() --> tpm2_unseal_cmd(). Well, the API is confusing, but the code seems to imply the parent should be present somehow. A key in NVRAM, like 81000001 is always present so it doesn't need to be loaded it can just be used as is. > Another problem here is, to build the policy to unseal the key, it > need to start an policy session, and transfer the session handle to > TPM2.0 unseal command. > In my keyctl command, I use tpm2.0 command to start the session and > get the handle, put it into the keyctl command like: > keyctl add trusted kmk "load `cat kmk.blob` keyhandle=0x81000001 > policyhandle=0x3000000" @u As I said, using policy handles simply won't scale, so we need to use the actual policy instead ... thus the policy should be passed into the kernel as part of the trusted key and the kernel itself would generate a policy session from the policy statements ... this approach is aready proven to be useful and functional in the tpm2 openssl engine code. James