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

[RFC] tools: add tpm2_policy tool for invoking libpolicy #2831

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

williamcroberts
Copy link
Member

Create a tpm2_policy tool that can read the FAPI JSON style policies
and:

  1. Instantiate them -> This process fills in anything missing in the
    template. TODO: How does this get handled, do we need to tweak any
    of the callbacks?

  2. Calculate them -> This process produces a list of hashes... TODO:
    Why? Is this a list of all the subordinate policies or can the json file
    have N policies where N > 1?

  3. Execute them -> Execute the policy on a session. TODO: Who is
    supposed to start the policy session as it seems to be 0?

Their are a lot of TODO items in this code. I'm looking for how we want
to use this, different tools, like tpm2_policyinit tpm2_policycalc and
tpm2_policyexec? Or an all in-one tool. Currently note that ONLY the
Execute needs an ESYS context, but instantiate should be filling stuff
in so it likely needs a context or the callbacks handled?

Signed-off-by: William Roberts william.c.roberts@intel.com

@idesai
Copy link
Member

idesai commented Sep 2, 2021

Wondering if this can be part of tpm2_createpolicy tool. There too we take an input to specify policy type. Except we rely on the TPM trial session to calculate the policy -- So that needs to change and also need to add the json parser to iterate through the policies.

What were the thoughts on executing policies? Why do we need this? I think we should limit the extent of this tool to calculate policies. It can quickly get complicated when the policy engine needs to interleave to record parameters set by other commands/ tools.

@nicowilliams
Copy link

The tpm2_* commands need to not have any dependency on data files not named on the command-line. If using FAPI means having to have files in /etc, that won't work for us.

My preference would be something like this:

  • get policyDigest: tpm2 policyexec --trial -L policy-digest-file policy-file.json
  • execute policy: tpm2 policyexec --session session.ctx policy-file.json

A way to specify files from which to get passwords for any passwords that need prompting might be useful. I would use a JSON file for that too, or I would provide an option to set the passwords right in the policy file (which can be done with jq or whatever).

I recommend leaving a policy creation CLI for last. Alternation (TPM2_PolicyOr()) is bound to make a policy creation command-line tool tricky. But if you want some ideas:

  • add a --policy-json FILE option to existing tpm2_policy* commands that alter the policy to add to it an entry for the current command
  • make tpm2_policyor w/ --policy-json FILE option make it so all the alternatives must be specified as JSON files and then write a single entry to the output JSON file (which must not exist already) with all the alternatives.

I believe you'll find that for commands like tpm2_policysigned and so on you'll need to add options for specifying priv/pub/PEM files that should be loaded at policy evaluation time and which then need to have their contents included in the JSON. Support for objects that should be loaded with TPM2_Load() and TPM2_LoadExternal() should be included.

As for FAPI, I think the context setup function takes a URI string value that currently has to be NULL. If you made this support passing in a directory, that would help make it more usable. Basically, there is no reason to expect N different TPM-using applications on a system to need to see one DB of extra metadata. Nor is there a reason to expect only one TPM to be used, especially with remote TPMs and encrypted sessions (though even for local TPMs we need encrypted sessions). The world of applications using a given TPM, and the world of objects that can exist transiently on that TPM , are unbounded, and different subsets can be distinct.

This is why I like the tpm2_* tools so much: the only abstraction is the automatic loading and saving of sessions and objects, leaving us users with an extremely thin abstraction on TPM 2.0 commands, which means just the TCG TPM 2.0 library parts 1 and 3 are enough to guide one to create complex policies and applications.

@williamcroberts
Copy link
Member Author

The tpm2_* commands need to not have any dependency on data files not named on the command-line. If using FAPI means having to have files in /etc, that won't work for us.

I want to make this very clear: this is not using FAPI. What it's doing is ripping out the policy engine part of FAPI to make it a consumable library. You pass it the policy file, and eventually through callbacks into the tool for things like passwords will happen. So I think you could program it with expect or we could come up with another interface. This will handle all the complexities of policies.

Ill have to read through the rest of comments and think about this more.

@nicowilliams
Copy link

I want to make this very clear: this is not using FAPI.

Got it. Thanks.

@nicowilliams
Copy link

BTW, I do like the idea of policies expressible in JSON, but it's not a very human readable language.

The language I've been play-thinking about looks like this:

declare command $signature: curl ...
declare prompt $pw: enter password: 
declare PEM signer:
--BEGIN PUBLIC KEY--
...
--END PUBLIC KEY--
or:
  ( secret --load-private some-priv-file --load-public some-pub-file --authvalue $pw )
  ( signed --nonce-tpm --signer $signer --signature $signature --policyref "...")

The idea is that each policy command is almost like a shell command, but with the ability to reference various data, some defined inline, some obtained by prompting, some obtained by running some external command. Conjunction would be done using ; between commands. Alternation would be as shown above.

I've got an implementation of a significantly simpler subset, written in bash. Bash is not a good language for this. But bash + jq is a decent combination for implementing an evaluator for policies expressed in JSON.

@nicowilliams
Copy link

nicowilliams commented Sep 16, 2021

FWIW: osresearch/safeboot#144

This is an exploration of what I'd like in a policy language. Yes, it's a prototype written in Bash (because it's in Safeboot, which is Bash).

Things I definitely want:

  • to use artifacts such as public keys of signers for TPM2_PolicySigned() and TPM2_PolicyAuthorize(), policyRef values, PCR values, etc., and:
    • to allow the caller to provide some such artifacts (in my prototype the caller of sbin/tpm2-policy can provide these)
    • to allow the policy to include in it some such artifacts (in my prototype the policy script can embed these as here documents)
  • to be able to construct artifacts during the execution of the policy (e.g., names/handles/saved contexts for keys imported and loaded during execution of the policy) (in my prototype the script can create artifacts in the current directory only, and can use artifacts only from it too, and the current directory is a temporary directory)
  • to refer to external sub-policies (e.g., ones authorized by TPM2_PolicyAuthorize()
    • possibly to download them as necessary
  • to prompt for authValues (passwords)
  • support for TPM2_PolicyOr(), of course
  • some PKIX support: for validating certificates for policy signers/authorizers, for example

I don't need looping. Conditionals are mostly interesting for reasons to do with TPM2_PolicyOr().

Safeboot.dev PR #144 isn't ready, and may well never finish, but it has much of the above and could easily be extended to do what it doesn't already.

UPDATE:
Working:
Initial test working:
If you get the tpm2_policy tool from the tss pr, this should work:
tpm2 policy /path/to/tpm2-tss/test/data/fapi/policy/pol_pcr16_0.json

Their are still many todo's to go through, but let's figure out the
interface into the library and go from there.

Create a tpm2_policy tool that can read the FAPI JSON style policies
and:

1. Instantiate them -> This process fills in anything missing in the
template. TODO: How does this get handled, do we need to tweak any
of the callbacks?

2. Calculate them -> This process produces a list of hashes... TODO:
   Why? Is this a list of all the subordinate policies or can the json file
   have N policies where N > 1?

3. Execute them -> Execute the policy on a session. TODO: Who is
supposed to start the policy session as it seems to be 0?

Their are a lot of TODO items in this code. I'm looking for how we want
to use this, different tools, like tpm2_policyinit tpm2_policycalc and
tpm2_policyexec? Or an all in-one tool. Currently note that ONLY the
Execute needs an ESYS context, but instantiate should be filling stuff
in so it likely needs a context or the callbacks handled?

Signed-off-by: William Roberts <william.c.roberts@intel.com>
William Roberts added 5 commits January 12, 2022 17:00
…y ctx

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

An epiphany I had recently is that for most TPM use cases there is one or maybe two commands that one wishes to execute with some saved key(s) that might have policies associated with them that might use other keys that have policies associated with them, and so on. It's not just TPM 2.0 EA policy that needs a language, but that even a sequence of desired commands, each with various parameters, needs a language.

Given such a language it should be possible to have a trivial API/CLI to execute the desired commands and all the possibly many commands impliedly necessary.

The only things the user should have to furnish are:

  • the description of the command(s) desired
  • values for any parameters required by those commands' objects/policies
    • these could be prompted for when not given explicitly

Then using TPMs could be very very easy.

One thing I think we need to never lose track of is the need to as much as possible always use a tpmKey for TPM2_StartAuthSession so that all sensitive parameters can be encrypted and so that all command / response parameters can be integrity protected via HMAC sessions. Obviously some commands must sometimes be executed outside the protection of HMAC sessions, like TPM2_CreatePrimary to "create" the tpmKey objects, but it should always be possible to check that the created primary's public key matches expectations (i.e., previously enrolled EKs, etc.). But in general it should be possible to authenticate the TPM to the user and to secure the communications with the TPM so that even if there is a local attacker -or even if the TPM is remote over a public network- the execution of the desired commands is secure.

@williamcroberts
Copy link
Member Author

An epiphany I had recently is that for most TPM use cases there is one or maybe two commands that one wishes to execute with some saved key(s) that might have policies associated with them that might use other keys that have policies associated with them, and so on. It's not just TPM 2.0 EA policy that needs a language, but that even a sequence of desired commands, each with various parameters, needs a language.

That sounds suspiciously like a programming language. The proposal would be some language to instruct which commands the host processor should send to the TPM.

Given such a language it should be possible to have a trivial API/CLI to execute the desired commands and all the possibly many commands impliedly necessary.

The only things the user should have to furnish are:

  • the description of the command(s) desired

  • values for any parameters required by those commands' objects/policies

    • these could be prompted for when not given explicitly

Then using TPMs could be very very easy.

Yes a meta language could be useful, but I don't see it making the TPM 2.0 easier to use. the CLI tools currently imply and figure out a lot of things based on what the user passes for options. The Python API is simpler compared to the C API as
well. The TPM is hard to use becuase it's wildly complex with lots of corner cases. The OpenSSL engine/provider and PKCS11 all provide a mechanism to use the TPM without really knowing how to use the TPM. Granted they only solve the crypto cases really.

One thing I think we need to never lose track of is the need to as much as possible always use a tpmKey for

Bind key can be just as valid and since it's started off of a secret theirs no need to verify it. The secret is never sent over the wire as well.

TPM2_StartAuthSession so that all sensitive parameters can be encrypted and so that all command / response parameters can be integrity protected via HMAC sessions. Obviously some commands must sometimes be executed outside the protection of HMAC sessions, like TPM2_CreatePrimary to "create" the tpmKey objects, but it should always be possible to check that the created primary's public key matches expectations (i.e., previously enrolled EKs, etc.). But in general it should be possible to authenticate the TPM to the user and to secure the communications with the TPM so that even if there is a local attacker -or even if the TPM is remote over a public network- the execution of the desired commands is secure.

Their was discussions on making a TCTI that modifies the commands being set to include session encryption and protections. This was users just get support without needing to worry about anything. FAPI does this as well for users.

@nicowilliams
Copy link

That sounds suspiciously like a programming language. The proposal would be some language to instruct which commands the host processor should send to the TPM.

There's no need for conditionals, loops, subroutines, lambdas, or variables, so it wouldn't be a programming language. But it would be a language, yes, or a schema for JSON (or XML, or YAML, or...).

In JSON imagine something like:

{
  "command":"TPM2_Sign",
  "keypriv":"...",
  "keypub":"...",
  "keypolicy":{"key policy description here":"..."}
}

or maybe

{
  "command":"TPM2_Sign",
  "key":"/path/to/key/description.json"
}

with the key descriptor having the key private/public/context parts and the policy descriptor.

If the key has an authValue and userWithAuth then the processor would have to prompt for that (or the user would have to provide it up front). Maybe we need a label for the prompt. Maybe we need a name for the key, so maybe all we need is a command and the name of a key, then you can find the key descriptor in some search path.

The policy descriptor itself might reference other keys. For example, a TPM2_PolicySigned, which might come with minimal instructions for how to get the signature (e.g., use a smartcard, or POST to some URI [possibly requiring authentication], etc.). Or TPM2_PolicySecret referencing a second key so that the user has to provide two passwords.

I believe a schema general enough for this is feasible.

@nicowilliams
Copy link

The OpenSSL engine/provider and PKCS11 all provide a mechanism to use the TPM without really knowing how to use the TPM.

That's a whole other topic for discussion. There is an enormous impedance mismatch between PKCS#11 and TPM 2.0 called policies. The only way to use a key with a complex policy through PKCS#11 would be if the only thing to prompt for is a password so that that can be the PKCS#11 PIN, and any other interactions would have to be out of band (like modal dialogs in a GUI display). Also, the tpm2-pkcs11 provider only supports keys created via it, and that makes it very difficult to do things like: create keys with some duplication policy, or import duplicated or external keys.

@nicowilliams
Copy link

Bind key can be just as valid and since it's started off of a secret theirs no need to verify it. The secret is never sent over the wire as well.

It's very dangerous to use a binKey and not a tpmKey: if the secret has low entropy then an eavesdropper can mount an offline dictionary attack.

@nicowilliams
Copy link

Their was discussions on making a TCTI that modifies the commands being set to include session encryption and protections. This was users just get support without needing to worry about anything. FAPI does this as well for users.

How could that possibly work if the app uses a tpmKey? I don't think it can work. The TCTI layer is too low in the stack for this.

@nicowilliams
Copy link

Yes a meta language could be useful, but I don't see it making the TPM 2.0 easier to use. the CLI tools currently imply and figure out a lot of things based on what the user passes for options.

Yes, the CLI tools are quite smart, but once you add a policy language (which is what this issue is about), you'll need to make sure that you have enough metadata about keys referenced by policies that the policy executor can be as smart as the utilities.

@williamcroberts
Copy link
Member Author

That sounds suspiciously like a programming language. The proposal would be some language to instruct which commands the host processor should send to the TPM.

There's no need for conditionals, loops, subroutines, lambdas, or variables, so it wouldn't be a programming language. But it would be a language, yes, or a schema for JSON (or XML, or YAML, or...).

In JSON imagine something like:

{
  "command":"TPM2_Sign",
  "keypriv":"...",
  "keypub":"...",
  "keypolicy":{"key policy description here":"..."}
}

or maybe

{
  "command":"TPM2_Sign",
  "key":"/path/to/key/description.json"
}

with the key descriptor having the key private/public/context parts and the policy descriptor.

If the key has an authValue and userWithAuth then the processor would have to prompt for that (or the user would have to provide it up front). Maybe we need a label for the prompt. Maybe we need a name for the key, so maybe all we need is a command and the name of a key, then you can find the key descriptor in some search path.

The policy descriptor itself might reference other keys. For example, a TPM2_PolicySigned, which might come with minimal instructions for how to get the signature (e.g., use a smartcard, or POST to some URI [possibly requiring authentication], etc.). Or TPM2_PolicySecret referencing a second key so that the user has to provide two passwords.

I believe a schema general enough for this is feasible.

It would be very easy to build something with pytss

@williamcroberts
Copy link
Member Author

The OpenSSL engine/provider and PKCS11 all provide a mechanism to use the TPM without really knowing how to use the TPM.

That's a whole other topic for discussion. There is an enormous impedance mismatch between PKCS#11 and TPM 2.0 called policies. The only way to use a key with a complex policy through PKCS#11 would be if the only thing to prompt for is a password so that that can be the PKCS#11 PIN, and any other interactions would have to be out of band (like modal dialogs in a GUI display).

I mean yes, but that's just PKCS11 and it has a provision that allows this in the spec. Some smartcards or readers have the pin pad or fingerprint readers, etc. It would all be out of band, but doable. Add a field for the key that contains the JSON policy and execute it, setting the callbacks to some out of band mechanism.

Also, the tpm2-pkcs11 provider only supports keys created via it, and that makes it very difficult to do things like: create keys with some duplication policy, or import duplicated or external keys.

That's not true, you can link in other keys from tpm2-tools or openssl engine/provider. You can even import raw keys. As long as the auth for the key is a simple password, it should just work.

@williamcroberts
Copy link
Member Author

Bind key can be just as valid and since it's started off of a secret theirs no need to verify it. The secret is never sent over the wire as well.

It's very dangerous to use a binKey and not a tpmKey: if the secret has low entropy then an eavesdropper can mount an offline dictionary attack.

If one it relying on bindKey, the auth shouldn't be trivial. That's on the user, so while it can be dangerous, theirs a lot of dangers in crypto.

@nicowilliams
Copy link

Also, the tpm2-pkcs11 provider only supports keys created via it, and that makes it very difficult to do things like: create keys with some duplication policy, or import duplicated or external keys.

That's not true, you can link in other keys from tpm2-tools or openssl engine/provider. You can even import raw keys. As long as the auth for the key is a simple password, it should just work.

Ah excellent. Sorry I got that wrong!

@williamcroberts
Copy link
Member Author

Yes a meta language could be useful, but I don't see it making the TPM 2.0 easier to use. the CLI tools currently imply and figure out a lot of things based on what the user passes for options.

Yes, the CLI tools are quite smart, but once you add a policy language (which is what this issue is about), you'll need to make sure that you have enough metadata about keys referenced by policies that the policy executor can be as smart as the utilities.

FAPI tss2 tools bind the policy to the key, while the tpm2-tools don't with the policy engine one could provide it as a separate argument and it would be on the caller to keep those things coupled unfortunately. However, if we add support for the tss2 pem format, I think we did IIRC, we could make a version that contains the JSON policy as well to couple things more easily.

@williamcroberts
Copy link
Member Author

I would recommend building something with pytss, and then make tpm2py-tools package [1]. I would love to re-write a set of command line tools in Python, while they can't be used everywhere, they'd be much simpler and way simpler to add features than the C tools. Or even Rust, now where rust is, i'd have no qualms using that language.

  1. If you would like a repo in this namespace, just let us know.

@nicowilliams
Copy link

nicowilliams commented Feb 1, 2023

Bind key can be just as valid and since it's started off of a secret theirs no need to verify it. The secret is never sent over the wire as well.

It's very dangerous to use a binKey and not a tpmKey: if the secret has low entropy then an eavesdropper can mount an offline dictionary attack.

If one it relying on bindKey, the auth shouldn't be trivial. That's on the user, so while it can be dangerous, theirs a lot of dangers in crypto.

One really has to always use HMAC sessions with tpmKey and parameter encryption to avoid active attackers (yes, even on the local bus). One can use TPMs remotely over a public network too, and the tools can't really know if that's the case, so one really has to authenticate the TPM to the client application, and if the bindAuth authValue is too simple then one really has to use a tpmKey.

There's a chicken-egg situation, of course, in that the first time one learns the public area of a tpmKey one may not be able to authenticate the TPM. If there are platform certificates then, yes, one can use those to securely learn the EKpub of the platform's TPM, but if not then one can only realistically learn the EKpub (and EKcert) via an ssh-style trust-on-first-use (TOFU). Once one has the EKpub one can then create other primaries over a session with the EK as the tpmKey. Once one has written down the EKpub and other primaries' public areas in local storage, one can use the TPM with a tpmKey every time for most things anyways -- everything but [re-]creating those keys.

EDIT: Imagine using a fast networked TPM for doing things like password validation in high-traffic sites. Clearly one would not use a slow, local dTPM for such things -- too slow, that! But if you're using a TPM over a network... OK, one could use TLS, and one probably should, but TPM2_StartAuthSession is a micro-TLS protocol, and policies can make it a very rich protocol.

There have been highly publicized active, local, on-the-bus attack techniques to compromise servers. It is essential, for example, that BMCs and BIOSes use tpmKey or very strong bindAuth to avoid these attacks, and not just the BMCs and BIOSes but also the kernel and TPM applications.

@nicowilliams
Copy link

I would recommend building something with pytss [...]

My colleagues and I have completely soured on Python for these things primarily on account of the bloat it leads to. For example, Safeboot is mostly bash-coded using tpm2-tools utilities so as to make it very small. Nowadays Rust and Go would be much better choices. @osresearch is particularly interested in keeping boot images small enough to be able to realistically use for PXE booting.

@williamcroberts
Copy link
Member Author

I would recommend building something with pytss [...]

My colleagues and I have completely soured on Python for these things primarily on account of the bloat it leads to. For example, Safeboot is mostly bash-coded using tpm2-tools utilities so as to make it very small. Nowadays Rust and Go would be much better choices. @osresearch is particularly interested in keeping boot images small enough to be able to realistically use for PXE booting.

Yeah if your environment is early boot, Python is usually out and even Go isn't optimal for size constraints. Rust would be a good choice.

@nicowilliams
Copy link

Yeah if your environment is early boot, Python is usually out and even Go isn't optimal for size constraints. Rust would be a good choice.

As long as the boot image can be <10MB it's probably fine. Python easily blows right through that.

@williamcroberts
Copy link
Member Author

Bind key can be just as valid and since it's started off of a secret theirs no need to verify it. The secret is never sent over the wire as well.

It's very dangerous to use a binKey and not a tpmKey: if the secret has low entropy then an eavesdropper can mount an offline dictionary attack.

If one it relying on bindKey, the auth shouldn't be trivial. That's on the user, so while it can be dangerous, theirs a lot of dangers in crypto.

One really has to always use HMAC sessions with tpmKey and parameter encryption to avoid active attackers (yes, even on the local bus). One can use TPMs remotely over a public network too, and the tools can't really know if that's the case, so one really has to authenticate the TPM to the client application, and if the bindAuth authValue is too simple then one really has to use a tpmKey.

Sure, bindKey only means you must have strong entropy as that is the only protection you have. But in some environments you may not have or can afford the time costs of asymmetric crypto.

There's a chicken-egg situation, of course, in that the first time one learns the public area of a tpmKey one may not be able to authenticate the TPM. If there are platform certificates then, yes, one can use those to securely learn the EKpub of the platform's TPM, but if not then one can only realistically learn the EKpub (and EKcert) via an ssh-style trust-on-first-use (TOFU). Once one has the EKpub one can then create other primaries over a session with the EK as the tpmKey. Once one has written down the EKpub and other primaries' public areas in local storage, one can use the TPM with a tpmKey every time for most things anyways -- everything but [re-]creating those keys.

TOFU is generally the model a lot of folks gravitate towards, myself included. I just recently added this into systemd, waiting on the PR to get merged: systemd/systemd#26185

EDIT: Imagine using a fast networked TPM for doing things like password validation in high-traffic sites. Clearly one would not use a slow, local dTPM for such things -- too slow, that! But if you're using a TPM over a network... OK, one could use TLS, and one probably should, but TPM2_StartAuthSession is a micro-TLS protocol, and policies can make it a very rich protocol.

With the cmd TCTI it's easy, you can get an SSH tunnel to the endpoint and then, I always suggest using sessions so you get those protections within the endpoint. Ie you don't need to trust your end point, just the TPM. The endpoint could only dos you.

There have been highly publicized active, local, on-the-bus attack techniques to compromise servers. It is essential, for example, that BMCs and BIOSes use tpmKey or very strong bindAuth to avoid these attacks, and not just the BMCs and BIOSes but also the kernel and TPM applications.

Yep, totally agree. I am in favor of the tpmKey and salted sessions when possible. I also prefer sessions over things like SPDM, because their are parts of designs where you may be concerned about introspection/alteration not on the bus itself. Consider an SGX/TDX design where bytes leaving the "enclave" are of concern, SPDM doesn't help you there.

@nicowilliams
Copy link

Sure, bindKey only means you must have strong entropy as that is the only protection you have. But in some environments you may not have or can afford the time costs of asymmetric crypto.

Right, and for that one should first use a session with a tpmKey to create a key with a high-entropy authValue, record the authValue in local storage, then use that key as the bindKey for symmetrically keying sessions.

TOFU is generally the model a lot of folks gravitate towards, myself included. I just recently added this into systemd, waiting on the PR to get merged: systemd/systemd#26185

Some platforms have platform certificates, but there's no standard way to retrieve them :( Still, if provided a platform certificate, it'd be good to use it for bootstrapping trust!

SPDM

As in https://www.dmtf.org/standards/spdm ?

@williamcroberts
Copy link
Member Author

Sure, bindKey only means you must have strong entropy as that is the only protection you have. But in some environments you may not have or can afford the time costs of asymmetric crypto.

Right, and for that one should first use a session with a tpmKey to create a key with a high-entropy authValue, record the authValue in local storage, then use that key as the bindKey for symmetrically keying sessions.

TOFU is generally the model a lot of folks gravitate towards, myself included. I just recently added this into systemd, waiting on the PR to get merged: systemd/systemd#26185

Some platforms have platform certificates, but there's no standard way to retrieve them :( Still, if provided a platform certificate, it'd be good to use it for bootstrapping trust!

Yes, that's what FAPI does. Unfortunately in early boot requirements it's difficult to validate the whole cert chain.

SPDM

As in https://www.dmtf.org/standards/spdm ?

Yeah, I think that's it. It's essentially bus level protection.

@williamcroberts
Copy link
Member Author

Their was discussions on making a TCTI that modifies the commands being set to include session encryption and protections. This was users just get support without needing to worry about anything. FAPI does this as well for users.

How could that possibly work if the app uses a tpmKey? I don't think it can work. The TCTI layer is too low in the stack for this.

If the app enables sessions you leave it be, else you modify the command and response buffers.

@nicowilliams
Copy link

If the app enables sessions you leave it be, else you modify the command and response buffers.

But the app might be using an HMAC session in order to satisfy an authorization requirement that it prove knowledge of an authValue that might be weak.

It's important to separate session keying for over-the-bus (or over-the-network) security from proving knowledge of weak passwords.

@williamcroberts
Copy link
Member Author

If the app enables sessions you leave it be, else you modify the command and response buffers.

But the app might be using an HMAC session in order to satisfy an authorization requirement that it prove knowledge of an authValue that might be weak.

It's important to separate session keying for over-the-bus (or over-the-network) security from proving knowledge of weak passwords.

Yes, it's a best effort. We won't be able to do it for every invocation based on the callers use of sessions. Our idea was to run in pedantic mode and return an error if we can't, so users know where things could be weak, then allow an ignore mode to bypass it.

The goal would be able to take a.legacy app that makes no use of sessions other than the implicitly started password session and enable session protections for them.

@nicowilliams
Copy link

The goal would be able to take a.legacy app that makes no use of sessions other than the implicitly started password session and enable session protections for them.

A worthy goal, but if you also provide the library that the apps use why not just do it all in the library?

I fear that trying to add security in the TCTI layer is going to make people unjustifiably feel good about weak applications. This also adds a fair bit of complexity at that layer.

@williamcroberts
Copy link
Member Author

The goal would be able to take a.legacy app that makes no use of sessions other than the implicitly started password session and enable session protections for them.

A worthy goal, but if you also provide the library that the apps use why not just do it all in the library?

We did, it's called FAPI

I fear that trying to add security in the TCTI layer is going to make people unjustifiably feel good about weak applications. This also adds a fair bit of complexity at that layer.

It would be a pluggable tcti like all the others, so it would just layer in, use it or don't. Yes, we don't want folks to get a false sense of security, that's why we would run in pedantic mode by default.

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