Subject: [PATCH] KEYS: asym_tpm: Switch to get_random_bytes()


> From: [email protected] <linux-integrity-
> [email protected]> On Behalf Of Jarkko Sakkinen
> Sent: Friday, October 4, 2019 2:27 PM
> Subject: EXT: Re: [PATCH] KEYS: asym_tpm: Switch to get_random_bytes()
>
> If you are able to call tpm_get_random(), the driver has already registered
> TPN as hwrng. With this solution you fail to follow the principle of defense in
> depth. If the TPM random number generator is compromissed (has a bug)
> using the entropy pool will decrease the collateral damage.

And if the entropy pool has a bug or is misconfigured, you lose everything.
That does not sound like defense in depth to me. In the real world
I am not aware of a single instance of RNG vulnerability on a TPM.
I am directly aware of several published vulnerabilities in embedded systems
due to a badly ported version of the kernel random pool. In addition,
the random generator in a TPM is hardware isolated, and less likely to be
vulnerable to side channel or memory manipulation errors. The TPM
RNG is typically FIPS certified. The use of the TPM RNG was a deliberate
design choice in trusted keys.

> > Third, as Mimi states, using a TPM is not a "regression". It would be
> > a regression to change trusted keys _not_ to use the TPM, because that
> > is what trusted keys are documented to provide to user space.
>
> For asym-tpm.c it is without a question a regression because of the evolution
> that has happened after trusted keys. For trusted keys using kernel rng
> would be improvement.

Perhaps this is a language issue, but you are not using "regression" correctly.
Changing to the kernel pool would not only be a debatable "improvement",
but also would certainly be a change to the documented trusted key
behavior, which I thought was frowned upon.

dave


2019-10-04 20:12:09

by Jerry Snitselaar

[permalink] [raw]
Subject: Re: [PATCH] KEYS: asym_tpm: Switch to get_random_bytes()

On Fri Oct 04 19, Jerry Snitselaar wrote:
>On Fri Oct 04 19, James Bottomley wrote:
>>On Fri, 2019-10-04 at 11:33 -0700, Jerry Snitselaar wrote:
>>>On Fri Oct 04 19, James Bottomley wrote:
>>>> On Fri, 2019-10-04 at 21:22 +0300, Jarkko Sakkinen wrote:
>>>> > On Thu, Oct 03, 2019 at 04:59:37PM -0700, James Bottomley wrote:
>>>> > > I think the principle of using multiple RNG sources for strong
>>>> > > keys is a sound one, so could I propose a compromise: We have
>>>> > > a tpm subsystem random number generator that, when asked for
>>>> > > <n> random bytes first extracts <n> bytes from the TPM RNG and
>>>> > > places it into the kernel entropy pool and then asks for <n>
>>>> > > random bytes from the kernel RNG? That way, it will always have
>>>> > > the entropy to satisfy the request and in the worst case, where
>>>> > > the kernel has picked up no other entropy sources at all it
>>>> > > will be equivalent to what we have now (single entropy source)
>>>> > > but usually it will be a much better mixed entropy source.
>>>> >
>>>> > I think we should rely the existing architecture where TPM is
>>>> > contributing to the entropy pool as hwrng.
>>>>
>>>> That doesn't seem to work: when I trace what happens I see us
>>>> inject 32 bytes of entropy at boot time, but never again. I think
>>>> the problem is the kernel entropy pool is push not pull and we have
>>>> no triggering event in the TPM to get us to push. I suppose we
>>>> could set a timer to do this or perhaps there is a pull hook and we
>>>> haven't wired it up correctly?
>>>>
>>>> James
>>>>
>>>
>>>Shouldn't hwrng_fillfn be pulling from it?
>>
>>It should, but the problem seems to be it only polls the "current" hw
>>rng ... it doesn't seem to have a concept that there may be more than
>>one. What happens, according to a brief reading of the code, is when
>>multiple are registered, it determines what the "best" one is and then
>>only pulls from that. What I think it should be doing is filling from
>>all of them using the entropy quality to adjust how many bits we get.
>>
>>James
>>
>
>Most of them don't even set quality, including the tpm, so they end up
>at the end of the list. For the ones that do I'm not sure how they determined
>the value. For example virtio-rng sets quality to 1000.

I should have added that I like that idea though.

2019-10-06 00:39:43

by Mimi Zohar

[permalink] [raw]
Subject: Re: [PATCH] KEYS: asym_tpm: Switch to get_random_bytes()

On Fri, 2019-10-04 at 15:11 -0700, James Bottomley wrote:

> +
> +/**
> + * tpm_get_random() - get random bytes influenced by the TPM's RNG
> + * @chip: a &struct tpm_chip instance, %NULL for the default chip
> + * @out: destination buffer for the random bytes
> + * @max: the max number of bytes to write to @out
> + *
> + * Uses the TPM as a source of input to the kernel random number
> + * generator and then takes @max bytes directly from the kernel. In
> + * the worst (no other entropy) case, this will return the pure TPM
> + * random number, but if the kernel RNG has any entropy at all it will
> + * return a mixed entropy output which doesn't rely on a single
> + * source.
> + *
> + * Return: number of random bytes read or a negative error value.
> + */
> +int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max)
> +{
> + int rc;
> +
> + rc = __tpm_get_random(chip, out, max);
> + if (rc <= 0)
> + return rc;
> + /*
> + * assume the TPM produces pure randomness, so the amount of
> + * entropy is the number of bits returned
> + */
> + add_hwgenerator_randomness(out, rc, rc * 8);
> + get_random_bytes(out, rc);

Using the TPM as a source of input to the kernel random number
generator is fine, but please don't change the meaning of trusted
keys.  The trusted-encrypted keys documentation clearly states
"Trusted Keys use a TPM both to generate and to seal the keys."

If you really want to use a different random number source instead of
the TPM, then define a new trusted key option (eg. rng=kernel), with
the default being the TPM.

Mimi


> +
> + return rc;
> +}
> EXPORT_SYMBOL_GPL(tpm_get_random);

2019-10-06 23:54:13

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH] KEYS: asym_tpm: Switch to get_random_bytes()

On Sat, Oct 05, 2019 at 08:38:53PM -0400, Mimi Zohar wrote:
> On Fri, 2019-10-04 at 15:11 -0700, James Bottomley wrote:
>
> > +
> > +/**
> > + * tpm_get_random() - get random bytes influenced by the TPM's RNG
> > + * @chip: a &struct tpm_chip instance, %NULL for the default chip
> > + * @out: destination buffer for the random bytes
> > + * @max: the max number of bytes to write to @out
> > + *
> > + * Uses the TPM as a source of input to the kernel random number
> > + * generator and then takes @max bytes directly from the kernel. In
> > + * the worst (no other entropy) case, this will return the pure TPM
> > + * random number, but if the kernel RNG has any entropy at all it will
> > + * return a mixed entropy output which doesn't rely on a single
> > + * source.
> > + *
> > + * Return: number of random bytes read or a negative error value.
> > + */
> > +int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max)
> > +{
> > + int rc;
> > +
> > + rc = __tpm_get_random(chip, out, max);
> > + if (rc <= 0)
> > + return rc;
> > + /*
> > + * assume the TPM produces pure randomness, so the amount of
> > + * entropy is the number of bits returned
> > + */
> > + add_hwgenerator_randomness(out, rc, rc * 8);
> > + get_random_bytes(out, rc);
>
> Using the TPM as a source of input to the kernel random number
> generator is fine, but please don't change the meaning of trusted
> keys. ?The trusted-encrypted keys documentation clearly states
> "Trusted Keys use a TPM both to generate and to seal the keys."
>
> If you really want to use a different random number source instead of
> the TPM, then define a new trusted key option (eg. rng=kernel), with
> the default being the TPM.

I'll add a patch that updates the documentation because it is clearly
not a good practice to use TPM to generate keys that are not keys
residing inside the TPM.

With TEE coming in, TPM is not the only hardware measure anymore sealing
the keys and we don't want a mess where every hardware asset does their
own proprietary key generation. The proprietary technology should only
take care of the sealing part.

/Jarkko

2019-10-07 00:06:12

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH] KEYS: asym_tpm: Switch to get_random_bytes()

On Fri, Oct 04, 2019 at 07:56:01PM +0000, Safford, David (GE Global Research, US) wrote:
>
> > From: [email protected] <linux-integrity-
> > [email protected]> On Behalf Of Jarkko Sakkinen
> > Sent: Friday, October 4, 2019 2:27 PM
> > Subject: EXT: Re: [PATCH] KEYS: asym_tpm: Switch to get_random_bytes()
> >
> > If you are able to call tpm_get_random(), the driver has already registered
> > TPN as hwrng. With this solution you fail to follow the principle of defense in
> > depth. If the TPM random number generator is compromissed (has a bug)
> > using the entropy pool will decrease the collateral damage.
>
> And if the entropy pool has a bug or is misconfigured, you lose everything.
> That does not sound like defense in depth to me. In the real world
> I am not aware of a single instance of RNG vulnerability on a TPM.
> I am directly aware of several published vulnerabilities in embedded systems
> due to a badly ported version of the kernel random pool. In addition,
> the random generator in a TPM is hardware isolated, and less likely to be
> vulnerable to side channel or memory manipulation errors. The TPM
> RNG is typically FIPS certified. The use of the TPM RNG was a deliberate
> design choice in trusted keys.

Hmm... so is RDRAND opcode FIPS certified.

Kernel has the random number generator for two reasons:

1. To protect against bugs in hwrng's.
2. To protect against deliberate backdoors in hwrng's.

How TPM RNG is guaranteed to protect against both 1 and 2?

If I would agree what you say, that'd be argument against using kernel
random number generator *anywhere* in the kernel. Even with the entropy
issues it is least worst thing to use for key generations for better
or worse.

/Jarkko

2019-10-08 23:51:02

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH] KEYS: asym_tpm: Switch to get_random_bytes()

On Mon, Oct 07, 2019 at 06:13:01PM -0400, Ken Goldman wrote:
> The TPM library specification states that the TPM must comply with NIST
> SP800-90 A.
>
> https://trustedcomputinggroup.org/membership/certification/tpm-certified-products/
>
> shows that the TPMs get third party certification, Common Criteria EAL 4+.
>
> While it's theoretically possible that an attacker could compromise
> both the TPM vendors and the evaluation agencies, we do have EAL 4+
> assurance against both 1 and 2.

Certifications do not equal to trust.

/Jarkko

2019-10-09 07:35:07

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH] KEYS: asym_tpm: Switch to get_random_bytes()

On Wed, Oct 09, 2019 at 02:53:39AM +0300, Jarkko Sakkinen wrote:
> On Wed, Oct 09, 2019 at 02:49:35AM +0300, Jarkko Sakkinen wrote:
> > On Mon, Oct 07, 2019 at 06:13:01PM -0400, Ken Goldman wrote:
> > > The TPM library specification states that the TPM must comply with NIST
> > > SP800-90 A.
> > >
> > > https://trustedcomputinggroup.org/membership/certification/tpm-certified-products/
> > >
> > > shows that the TPMs get third party certification, Common Criteria EAL 4+.
> > >
> > > While it's theoretically possible that an attacker could compromise
> > > both the TPM vendors and the evaluation agencies, we do have EAL 4+
> > > assurance against both 1 and 2.
> >
> > Certifications do not equal to trust.
>
> And for trusted keys the least trust solution is to do generation
> with the kernel assets and sealing with TPM. With TEE the least
> trust solution is equivalent.
>
> Are you proposing that the kernel random number generation should
> be removed? That would be my conclusion of this discussion if I
> would agree any of this (I don't).

The whole point of rng in kernel has been to use multiple entropy
sources in order to disclose the trust issue.

Even with weaker entropy than TPM RNG it is still a better choice for
*non-TPM* keys because of better trustworthiness. Using only TPM RNG is
a design flaw that has existed probably because when trusted keys were
introduced TPM was more niche than it is today.

Please remember that a trusted key is not a TPM key. The reality
distortion field is strong here it seems.

/Jarkko

2019-10-09 07:42:42

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH] KEYS: asym_tpm: Switch to get_random_bytes()

On Wed, Oct 09, 2019 at 10:33:15AM +0300, Jarkko Sakkinen wrote:
> On Wed, Oct 09, 2019 at 02:53:39AM +0300, Jarkko Sakkinen wrote:
> > On Wed, Oct 09, 2019 at 02:49:35AM +0300, Jarkko Sakkinen wrote:
> > > On Mon, Oct 07, 2019 at 06:13:01PM -0400, Ken Goldman wrote:
> > > > The TPM library specification states that the TPM must comply with NIST
> > > > SP800-90 A.
> > > >
> > > > https://trustedcomputinggroup.org/membership/certification/tpm-certified-products/
> > > >
> > > > shows that the TPMs get third party certification, Common Criteria EAL 4+.
> > > >
> > > > While it's theoretically possible that an attacker could compromise
> > > > both the TPM vendors and the evaluation agencies, we do have EAL 4+
> > > > assurance against both 1 and 2.
> > >
> > > Certifications do not equal to trust.
> >
> > And for trusted keys the least trust solution is to do generation
> > with the kernel assets and sealing with TPM. With TEE the least
> > trust solution is equivalent.
> >
> > Are you proposing that the kernel random number generation should
> > be removed? That would be my conclusion of this discussion if I
> > would agree any of this (I don't).
>
> The whole point of rng in kernel has been to use multiple entropy
> sources in order to disclose the trust issue.
>
> Even with weaker entropy than TPM RNG it is still a better choice for
> *non-TPM* keys because of better trustworthiness. Using only TPM RNG is
> a design flaw that has existed probably because when trusted keys were
> introduced TPM was more niche than it is today.
>
> Please remember that a trusted key is not a TPM key. The reality
> distortion field is strong here it seems.

And why not use RDRAND on x86 instead of TPM RNG here? It is also FIPS
compliant and has less latency than TPM RNG. :-) If we go with this
route, lets pick the HRNG that performs best.

/Jarkko

2019-10-09 08:04:16

by Pascal Van Leeuwen

[permalink] [raw]
Subject: RE: [PATCH] KEYS: asym_tpm: Switch to get_random_bytes()

> -----Original Message-----
> From: [email protected] <[email protected]> On Behalf Of
> Jarkko Sakkinen
> Sent: Wednesday, October 9, 2019 9:33 AM
> To: Ken Goldman <[email protected]>
> Cc: Safford, David (GE Global Research, US) <[email protected]>; Mimi Zohar
> <[email protected]>; [email protected]; [email protected]; open
> list:ASYMMETRIC KEYS <[email protected]>; open list:CRYPTO API <linux-
> [email protected]>; open list <[email protected]>
> Subject: Re: [PATCH] KEYS: asym_tpm: Switch to get_random_bytes()
>
> On Wed, Oct 09, 2019 at 02:53:39AM +0300, Jarkko Sakkinen wrote:
> > On Wed, Oct 09, 2019 at 02:49:35AM +0300, Jarkko Sakkinen wrote:
> > > On Mon, Oct 07, 2019 at 06:13:01PM -0400, Ken Goldman wrote:
> > > > The TPM library specification states that the TPM must comply with NIST
> > > > SP800-90 A.
> > > >
> > > > https://trustedcomputinggroup.org/membership/certification/tpm-certified-products/
> > > >
> > > > shows that the TPMs get third party certification, Common Criteria EAL 4+.
> > > >
> > > > While it's theoretically possible that an attacker could compromise
> > > > both the TPM vendors and the evaluation agencies, we do have EAL 4+
> > > > assurance against both 1 and 2.
> > >
> > > Certifications do not equal to trust.
> >
> > And for trusted keys the least trust solution is to do generation
> > with the kernel assets and sealing with TPM. With TEE the least
> > trust solution is equivalent.
> >
> > Are you proposing that the kernel random number generation should
> > be removed? That would be my conclusion of this discussion if I
> > would agree any of this (I don't).
>
> The whole point of rng in kernel has been to use multiple entropy
> sources in order to disclose the trust issue.
>
I do understand that, and combining multiple entropy sources, if
you have them available to get _more_ entropy is a good idea, at
least in theory. But ...

How do I know the mixing of entropy happens properly? Especially
if I'm not capable of judging this by myself.
And how do I know the SW entropy pool and/or code cannot be influenced
_somehow_? (either directly or indirectly by influencing one of the
contributors). More code and/or HW involved means more attack vectors
and complication of the review process.

The point is, if you want to certify such an application, you would
have to have _all_ contributors _plus_ the kernel rng code certified.
And you would have to have it _recertified_ every time a _single_
component - including the kernel code itself! - changes.

> Even with weaker entropy than TPM RNG it is still a better choice for
> *non-TPM* keys because of better trustworthiness.
>
"Even with weaker entropy"? Now that's just silly. If you _know_ and
_trust_ the TPM to have _better_ entropy, then obviously that is the
better choice. I guess the key word being the trust you don't have.

> Using only TPM RNG is
> a design flaw that has existed probably because when trusted keys were
> introduced TPM was more niche than it is today.
>
For non-TPM keys, possibly. Assuming the kernel RNG indeed adds
(or at least does not weaken) entropy. And assuming I _can_ trust
the kernel RNG implementation. Question is: why would I trust that
more than the TPM implementation? Sure, I could look at the code,
but would I truly and fully understand it? (so maybe _I_ would,
but would Joe Random User?)

> Please remember that a trusted key is not a TPM key. The reality
> distortion field is strong here it seems.
>
Agree. But you should not mess with the possibility to generate
keys based on _just_ the TPM RNG _where that is required_ (and
perhaps _only_ where that is required, if possible)

> /Jarkko

Regards,
Pascal van Leeuwen
Silicon IP Architect, Multi-Protocol Engines @ Verimatrix
http://www.insidesecure.com

2019-10-09 08:10:25

by Pascal Van Leeuwen

[permalink] [raw]
Subject: RE: [PATCH] KEYS: asym_tpm: Switch to get_random_bytes()

> -----Original Message-----
> From: [email protected] <[email protected]> On Behalf Of
> Jarkko Sakkinen
> Sent: Wednesday, October 9, 2019 9:42 AM
> To: Ken Goldman <[email protected]>
> Cc: Safford, David (GE Global Research, US) <[email protected]>; Mimi Zohar
> <[email protected]>; [email protected]; [email protected]; open
> list:ASYMMETRIC KEYS <[email protected]>; open list:CRYPTO API <linux-
> [email protected]>; open list <[email protected]>
> Subject: Re: [PATCH] KEYS: asym_tpm: Switch to get_random_bytes()
>
> On Wed, Oct 09, 2019 at 10:33:15AM +0300, Jarkko Sakkinen wrote:
> > On Wed, Oct 09, 2019 at 02:53:39AM +0300, Jarkko Sakkinen wrote:
> > > On Wed, Oct 09, 2019 at 02:49:35AM +0300, Jarkko Sakkinen wrote:
> > > > On Mon, Oct 07, 2019 at 06:13:01PM -0400, Ken Goldman wrote:
> > > > > The TPM library specification states that the TPM must comply with NIST
> > > > > SP800-90 A.
> > > > >
> > > > > https://trustedcomputinggroup.org/membership/certification/tpm-certified-products/
> > > > >
> > > > > shows that the TPMs get third party certification, Common Criteria EAL 4+.
> > > > >
> > > > > While it's theoretically possible that an attacker could compromise
> > > > > both the TPM vendors and the evaluation agencies, we do have EAL 4+
> > > > > assurance against both 1 and 2.
> > > >
> > > > Certifications do not equal to trust.
> > >
> > > And for trusted keys the least trust solution is to do generation
> > > with the kernel assets and sealing with TPM. With TEE the least
> > > trust solution is equivalent.
> > >
> > > Are you proposing that the kernel random number generation should
> > > be removed? That would be my conclusion of this discussion if I
> > > would agree any of this (I don't).
> >
> > The whole point of rng in kernel has been to use multiple entropy
> > sources in order to disclose the trust issue.
> >
> > Even with weaker entropy than TPM RNG it is still a better choice for
> > *non-TPM* keys because of better trustworthiness. Using only TPM RNG is
> > a design flaw that has existed probably because when trusted keys were
> > introduced TPM was more niche than it is today.
> >
> > Please remember that a trusted key is not a TPM key. The reality
> > distortion field is strong here it seems.
>
> And why not use RDRAND on x86 instead of TPM RNG here? It is also FIPS
> compliant and has less latency than TPM RNG. :-) If we go with this
> route, lets pick the HRNG that performs best.
>
There's certification and certification. Not all certificates are
created equally. But if it matches your specific requirements, why not.
There's a _lot_ of HW out there that's not x86 though ...

And: is RDRAND certified for _all_ x86 processors? Or just Intel?
Or perhaps even only _specific (server) models_ of CPU's?
I also know for a fact that some older AMD processors had a broken
RDRAND implementation ...

So the choice really should be up to the application or user.

Regards,
Pascal van Leeuwen
Silicon IP Architect, Multi-Protocol Engines @ Verimatrix
http://www.insidesecure.com