[Tpm2] Better understanding auth/object hierarchies

Stewart Webb <[email protected]> Thu, 22 Jun 2023 18:06:20 +1000
Newsgroups dev.linux.lists.tpm2
Message-ID <CAKfZqkGug+w7FznhcKHBWwQdQS25HGVd2DAFaw5_uEcYrhd2hQ@mail.gmail.com>
Hi there,

I have been investigating using the TPM2 for secure persistence of secrets.
It seems sealing objects are the way to go for this kind of thing.

I am hoping someone here might be able to better explain how sealing
objects are related to the parent objects they are created and loaded
under, especially when password auth values are involved. I've been a bit
confused by some examples I've put together that allow various operations
without supplying the passwords I would have thought were required.

(note: many of the examples below require calls to tpm2_flushcontext to
clear out space for intermediate object loading, but I have excluded them
for brevity)

As part of my evaluation I have learnt that sealing objects must always be
created underneath some other 'primary object'/primary key that must be
created first.

    # make a new primary key
    $ tpm2_createprimary -C o -c testprim.ctx
    # make a new sealing object under this primary key
    $ tpm2_create -u testseal.pub -r testseal.priv -i hunter2.txt -C
testprim.ctx


These primary objects can optionally be created with password auth values
on them. As you'd expect, trying to create a sealing object via a
password-protected primary object without supplying its password doesn't
work:

    $ tpm2_createprimary -C o -p str:testpwd -c testprim-wauth.ctx
    $ tpm2_create -u testseal-wpauth.pub -r testseal-wpauth.priv -i
hunter2.txt -C testprim-wauth.ctx
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 (0x0000098e)    ERROR: Esys_Create(0x98E) -
tpm:session(1):the authorization HMAC check failed and DA counter
incremented    ERROR: Unable to run tpm2_create    $ tpm2_create -u
testseal-wpauth.pub -r testseal-wpauth.priv -i hunter2.txt -C
testprim-wauth.ctx -P str:testpwd    # OK


What confuses me a bit is that loading and unsealing one of these
created-under-the-auth-protected-primary-key objects works fine if the
loading is done under a non-authed primary key:

    # no password required here
    $ tpm2_load -C testprim.ctx -u testseal-wpauth.pub -r
testseal-wpauth.priv -n testseal-loadedwnopauth.name -c
testseal-loadedwnopauth.ctx
    $ tpm2_unseal -c testseal-loadedwnopauth.ctx
    hunter2


However, if loading under the auth-value-protected primary key, the
password is required as expected for the loading...

    # Try load without password
    $ tpm2_load -C testprim-wauth.ctx -u testseal-wpauth.pub -r
testseal-wpauth.priv -n testseal-loadedwpauth.name -c
testseal-loadedwpauth.ctx
WARNING:esys:src/tss2-esys/api/Esys_Load.c:324:Esys_Load_Finish()
Received TPM Error
ERROR:esys:src/tss2-esys/api/Esys_Load.c:112:Esys_Load() Esys Finish
ErrorCode (0x0000098e)    ERROR: Eys_Load(0x98E) - tpm:session(1):the
authorization HMAC check failed and DA counter incremented    ERROR:
Unable to run tpm2_load    # with password:    $ tpm2_load -C
testprim-wauth.ctx -u testseal-wpauth.pub -r testseal-wpauth.priv -n
testseal-loadedwpauth.name -c testseal-loadedwpauth.ctx -P str:testpwd
   # OK


...but the unsealing still works without a password too. I'm assuming this
is because the sealing object itself has no password on it.

$ tpm2_unseal -c testseal-loadedwpauth.ctx
hunter2

If the sealing object itself is given a password auth value (-p flag in
tpm2_create) then it can never be unsealed without that password, which is
expected behaviour, so that at least works fine.

I am just confused as to why things created under password-protected
primary keys can still be seemingly later used without needing that
password? Is the password purely for the ability to create subsequent child
objects under the primary key? Or am I missing something here?

Cheers,
Stewart Webb