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

Session config changes #2700

Merged
merged 2 commits into from
Apr 15, 2021

Conversation

williamcroberts
Copy link
Member

No description provided.

William Roberts added 2 commits April 14, 2021 14:51
We're linux folks, we like things neat and tidy. Get rid of the starting
newline and trailing double newline.

Signed-off-by: William Roberts <william.c.roberts@intel.com>
Print the TPM handle so folks can pass it to APIs that need TPM handle,
like the kernel keyring.

Signed-off-by: William Roberts <william.c.roberts@intel.com>
@williamcroberts
Copy link
Member Author

@idesai can I get these on 5.1, requested feature from mailing list.

@codecov
Copy link

codecov bot commented Apr 14, 2021

Codecov Report

Merging #2700 (7b7d1d4) into master (e1575bc) will decrease coverage by 0.00%.
The diff coverage is 83.33%.

❗ Current head 7b7d1d4 differs from pull request most recent head 56445e2. Consider uploading reports for the commit 56445e2 to get more accurate results
Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2700      +/-   ##
==========================================
- Coverage   75.60%   75.60%   -0.01%     
==========================================
  Files         170      170              
  Lines       19971    19975       +4     
==========================================
+ Hits        15100    15103       +3     
- Misses       4871     4872       +1     
Impacted Files Coverage Δ
tools/tpm2_sessionconfig.c 58.25% <83.33%> (+0.67%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e1575bc...56445e2. Read the comment docs.

@idesai
Copy link
Member

idesai commented Apr 14, 2021

@williamcroberts IIUC the ask was to retain the session handle on the TPM. When the session is closed with this tool, that handle may not be valid anymore even without RM in play. This tool will need another option like --disable-flush to prevent closing the session. This should then have a warning message indicating that if RM is in play then the TPM HANDLE could be possibly changed.

@williamcroberts
Copy link
Member Author

@williamcroberts IIUC the ask was to retain the session handle on the TPM. When the session is closed with this tool, that handle may not be valid anymore even without RM in play. This tool will need another option like --disable-flush to prevent closing the session. This should then have a warning message indicating that if RM is in play then the TPM HANDLE could be possibly changed.

It should be resident in the tpm with continue session no?

@idesai
Copy link
Member

idesai commented Apr 14, 2021

@williamcroberts IIUC the ask was to retain the session handle on the TPM. When the session is closed with this tool, that handle may not be valid anymore even without RM in play. This tool will need another option like --disable-flush to prevent closing the session. This should then have a warning message indicating that if RM is in play then the TPM HANDLE could be possibly changed.

It should be resident in the tpm with continue session no?

You are right. I assumed tpm2_session_close will always invoke flush, but it doesn't unless chosen with a boolean. And in sessionconfig we don't. What about the RM?

@williamcroberts
Copy link
Member Author

@williamcroberts IIUC the ask was to retain the session handle on the TPM. When the session is closed with this tool, that handle may not be valid anymore even without RM in play. This tool will need another option like --disable-flush to prevent closing the session. This should then have a warning message indicating that if RM is in play then the TPM HANDLE could be possibly changed.

It should be resident in the tpm with continue session no?

You are right. I assumed tpm2_session_close will always invoke flush, but it doesn't unless chosen with a boolean.

Yeah the only thing that should ALWAYS call flush is the flushcontext tool. Otherwise let it be stateful with someone turning off continuesession flag. Since it's on be default, turning it off, user be ware. The session.ctx file will be invalidated.

And in sessionconfig we don't. What about the RM?

THIS is the feature that the in-kernel RM is missing. tpm2-abrmd handles sessions between command invocations (I think its the ungapping problem IIUC). This is why the session tests are in the "with abrmd tests only" category.

@jopelima
Copy link
Contributor

This change addresses the issue of getting the session handle just fine.

What I'm not sure is if it addresses the issue of having the session loaded on the TPM, if the interface you're going through doesn't let you pass the context file along.

To describe the use-case, I'm preparing a policy session in userspace, and want to pass it on to the kernel keyring trusted keys subsystem so that it can unseal the keyblob I'm sending to it.

I followed your discussion above, but I'm not sure I'm understanding all the details correctly.

My understanding of how the tools are operating is that when the tool initialises the context is loaded back into TPM memory (there is a call to tpm2_context_load somewhere down the stack) and when the tool finishes executing the context is swapped back out of TPM memory (the files_save_tpm_context_to_file call tpm2_context_save).

This means that, once the tool finishes executing, the session is not resident on tpm memory anymore, and hence it's not usable if you have to address it by handle (rather than by context file). What I get from your explanation is that with tpm2_abrmd the RM handles that transition, even if you are not passing the context file explicitly?

In any case, I'm using the kernel RM for the userspace preparation, and (AFAICT) the kernel keyring interacts directly with the TPM chip, skipping the RM altogether, so I'd have to have the session resident on the TPM so that I can pass the handle to the kernel.

The tool I was proposing in #2701 was doing the first part that most tools are doing, executing the tpm2_context_load and leaving it active on the TPM.

Am I just reading this all wrong, and you can address the session by handle always without having to rely on the context file?

@williamcroberts
Copy link
Member Author

This change addresses the issue of getting the session handle just fine.

What I'm not sure is if it addresses the issue of having the session loaded on the TPM, if the interface you're going through doesn't let you pass the context file along.

Nothing gets unloaded from the TPM unless something occurs:

  1. someone calls flushcontext.
  2. you're using a resource manager.

So this means two things:

  1. if your accessing something via --tcti="device:/dev/tpm0" everything hangs out in the TPM. (see notes below)
  2. If you access it through tpm2-abrmd, it knows not to flush session contexts on tool process exit. However, the in-kernel one will flush it. Which means you need to call tpm2_flushcontext on the session.ctx file, or UNSET the continuesession bit on the final command which makes the TPM flush the session.

Notes:
When you're using tpm2-tools directly against a TPM, since each tool calls contextload, and contextsave, you'll end up with transient objects floating around. So you'll need to manage those manually with flush context calls or you'll run out of TPM memory.

To describe the use-case, I'm preparing a policy session in userspace, and want to pass it on to the kernel keyring trusted keys subsystem so that it can unseal the keyblob I'm sending to it.

I followed your discussion above, but I'm not sure I'm understanding all the details correctly.

My understanding of how the tools are operating is that when the tool initialises the context is loaded back into TPM memory (there is a call to tpm2_context_load somewhere down the stack) and when the tool finishes executing the context is swapped back out of TPM memory (the files_save_tpm_context_to_file call tpm2_context_save).

This means that, once the tool finishes executing, the session is not resident on tpm memory anymore, and hence it's not usable if you have to address it by handle (rather than by context file). What I get from your explanation is that with tpm2_abrmd the RM handles that transition, even if you are not passing the context file explicitly?

In any case, I'm using the kernel RM for the userspace preparation, and (AFAICT) the kernel keyring interacts directly with the TPM chip, skipping the RM altogether, so I'd have to have the session resident on the TPM so that I can pass the handle to the kernel.

The tool I was proposing in #2701 was doing the first part that most tools are doing, executing the tpm2_context_load and leaving it active on the TPM.

Am I just reading this all wrong, and you can address the session by handle always without having to rely on the context file?

The context file is just a mechanism to move state from one command to another in the presence of an RM, because the RM flushes everything when processes exit. However, sessions cannot be reloaded from a saved state, which means the RM needs to be aware of the context save, and not flush it, so it can be reloaded from the context file. It's a weird quark that tpm2-abrmd supports, in-kernel RM doesn't. You don't even need to worry about it with direct TPM access.

So when you do something like:
tpm2_startauthsession --policy-session -S session.ctx
tpm2_policy -S session.ctx
... more policy commands ...
tpm2_sessionconfig session.ctx

That whole lifecycle, the TPM handle never changes, and the handle is resident in the TPM when using tpm2-abrmd OR direct access.

It's not until tpm2_flushcontext, or a command is invoked with continuesession bit disabled, that the session goes away and is unrecoverable.

Does that explain it better?

@jopelima
Copy link
Contributor

Thanks for your explanation William, I think it does cover my concerns yes.

I think what ended up getting me confused was reading somewhere on the standard that the contextload/save commands where meant to exchange a context file for a handle and vice-versa, and that the two couldn't exist at the same time, but I think I understand it now.

@idesai
Copy link
Member

idesai commented Apr 15, 2021

Tested this

~idesai$ tpm2_clear
~idesai$ tpm2_getcap handles-saved-session
~idesai$ tpm2_startauthsession -S session.ctx --policy-session
~idesai$ tpm2_getcap handles-saved-session
- 0x2000000
~idesai$ tpm2_sessionconfig session.ctx
Session-Handle: 0x03000000
Session-Attributes: continuesession
~idesai$ tpm2_flushcontext session.ctx
~idesai$ tpm2_getcap handles-saved-session

@idesai idesai merged commit 788342d into tpm2-software:master Apr 15, 2021
@jopelima
Copy link
Contributor

jopelima commented May 4, 2021

Hi @williamcroberts,

I followed your previous recommendation, but it doesn't seem to address the root issue I was highlighting with the session being "saved" out of the TPM.

The example below uses the kernel keyring trusted keys subsystem which (currently) requires a policy session handle to be provided, when the trusted key is bound to a policy on creation. To obviate any influence the in-kernel RM may be having, I'm executing all commands directly agains the TPM.

Trusted key creation:

jlima:~$ sudo tpm2_startauthsession -T "device:/dev/tpm0" -S session.dat
jlima:~$ sudo tpm2_policypcr -T "device:/dev/tpm0" -S session.dat -l "sha1:0,4,7+sha256:0,4,7" -L pcr.policy
1b991e675832f1e75372f3e2cfe8f32f461aacb00d24f330bbb94bb0f391c29f
jlima:~$ sudo tpm2_flushcontext session.dat
jlima:~$
jlima:~$
jlima:~$ keyctl add trusted kmk "new 32 keyhandle=0x81000001 hash=sha256 policydigest=1b991e675832f1e75372f3e2cfe8f32f461aacb00d24f330bbb94bb0f391c29f" @u
74521619
jlima:~$ keyctl pipe 74521619 > kmk.blob
jlima:~$ keyctl unlink 74521619
1 links removed

At the end of the keyctl sequence, we have the trusted key sealed to the TPM owner primary key, using the PCR policy defined.

Trusted key loading:

jlima:~$ sudo tpm2_startauthsession -T "device:/dev/tpm0" -S session.dat --policy-session
jlima:~$ sudo tpm2_policypcr -T "device:/dev/tpm0" -S session.dat -l "sha1:0,4,7+sha256:0,4,7" -L pcr.policy
1b991e675832f1e75372f3e2cfe8f32f461aacb00d24f330bbb94bb0f391c29f
jlima:~$ sudo tpm2_getcap -T "device:/dev/tpm0" handles-saved-session
- 0x2000000
jlima:~$ sudo tpm2_getcap -T "device:/dev/tpm0" handles-loaded-session
jlima:~$
jlima:~$
jlima:~$ keyctl add trusted kmk "load `cat kmk.blob` keyhandle=0x81000001 hash=sha256 policyhandle=0x02000000" @u
add_key: Operation not permitted
jlima:~$ keyctl add trusted kmk "load `cat kmk.blob` keyhandle=0x81000001 hash=sha256 policyhandle=0x03000000" @u
add_key: Operation not permitted

The operation itself doesn't give much feedback, but looking at dmesg output the TPM is responding with error 2328 for both load attempts (the one using the session handle currently reported as loaded on the TPM and the one with the session handle as reported by the sessionconfig command.

jlima:~$ tpm2_rc_decode 2328
tpm:warn(2.0): the 1st authorization session handle references a session that is not loaded

Using the same session context file, and using the contextload utility proposed before:

jlima:~$ sudo tpm2_contextload -T "device:/dev/tpm0" -S session.dat
Session-Handle: 0x03000000
jlima:~$ sudo tpm2_getcap -T "device:/dev/tpm0" handles-saved-session
jlima:~$ sudo tpm2_getcap -T "device:/dev/tpm0" handles-loaded-session
- 0x3000000
jlima:~$
jlima:~$
jlima:~$ keyctl add trusted kmk "load `cat kmk.blob` keyhandle=0x81000001 hash=sha256 policyhandle=0x03000000" @u
add_key: Operation not permitted

While we still get an error, looking at dmesg output we're getting a different error code (2466).

jlima:~$ tpm2_rc_decode 2466
tpm:session(1):authorization failure without DA implications

I'm assuming this error is being thrown due to the fact the kernel is not calculating the HMAC value for the session, but it shows if we context load before passing the handle along it can seemingly be accessed by the TPM, when it can't if we don't do the contextload.

Do you think I am doing something wrong still, or is the above a correct interpretation of the situation?

Thanks!

@williamcroberts
Copy link
Member Author

@jopelima I don't see anything that strikes me as incorrect. But I don't see the object your creating that you would like to use. Are you sure that the created object and the policy are usable, did you verify in userspace?

I see the issue now, it's in the saved handles versus loaded handles state. So we would probably want to go ahead with a context load command tool.

@idesai any other ways you can think of?

@williamcroberts
Copy link
Member Author

@jopelima I don't see anything that strikes me as incorrect. But I don't see the object your creating that you would like to use. Are you sure that the created object and the policy are usable, did you verify in userspace?

I see the issue now, it's in the saved handles versus loaded handles state. So we would probably want to go ahead with a context load command tool.

@idesai any other ways you can think of?

I guess another option would be an option and ENV var to disable load/save. So when folks are not using an RM, they don't have to worry about the context load/save, and having to manage the additional transient objects. But I think that might complicate the flow even more thinking through it.

@jopelima
Copy link
Contributor

jopelima commented May 4, 2021

I assume the object you're referring to @williamcroberts is the sealed object itself, and that is created and loaded by the kernel itself when using the trusted keys implementation. If it was the sealing key, it's a standard primary key:

jlima:~$ tpm2_createprimary -C o -G rsa2048:aes128cfb -g sha256 -c srk.ctx -a 'restricted|decrypt|fixedtpm|fixedparent|sensitivedataorigin|userwithauth|noda'
jlima:~$ tpm2_evictcontrol -c srk.ctx 0x81000001-Q

I haven't verified before, but did verify now and the object I got exported from the kernel keyring can be loaded into the TPM and unsealed in userspace using the defined policy (I had to redefine the example I gave above a bit, because the kernel implementation is restricted to SHA1 hashes, but the result is not affected).

I had a skeleton implementation of the contextload tool that I can bring back up as a PR if you'd like. It made sense to me to have the reverse operation as well (contextsave) but I can't quite tell at this point how to do it with the knowledge I have of the tools and tss implementation.

@williamcroberts
Copy link
Member Author

I assume the object you're referring to @williamcroberts is the sealed object itself, and that is created and loaded by the kernel itself when using the trusted keys implementation. If it was the sealing key, it's a standard primary key:

jlima:~$ tpm2_createprimary -C o -G rsa2048:aes128cfb -g sha256 -c srk.ctx -a 'restricted|decrypt|fixedtpm|fixedparent|sensitivedataorigin|userwithauth|noda'
jlima:~$ tpm2_evictcontrol -c srk.ctx 0x81000001-Q

I haven't verified before, but did verify now and the object I got exported from the kernel keyring can be loaded into the TPM and unsealed in userspace using the defined policy (I had to redefine the example I gave above a bit, because the kernel implementation is restricted to SHA1 hashes, but the result is not affected).

I had a skeleton implementation of the contextload tool that I can bring back up as a PR if you'd like. It made sense to me to have the reverse operation as well (contextsave) but I can't quite tell at this point how to do it with the knowledge I have of the tools and tss implementation.

Yeah unless @idesai has a better thought, I think contextload will be needed. contextsave would be tricky, because you would need a handle you want to context save, but the tools already did that on exit. So I don't see a use for that one.

@jopelima
Copy link
Contributor

jopelima commented May 5, 2021

PR submitted for tpm2_contextload tool: #2717

@williamcroberts williamcroberts deleted the session-config-changes branch July 14, 2022 16:28
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

Successfully merging this pull request may close these issues.

None yet

3 participants