Page MenuHomeFreeBSD

tpm: Harvest entropy from TPM 1.2 devices
Needs ReviewPublic

Authored by kbowling on Fri, Aug 28, 12:43 AM.
Tags
None
Referenced Files
F172250522: D59239.diff
Thu, Sep 17, 6:26 AM
Unknown Object (File)
Tue, Sep 15, 4:27 PM
Unknown Object (File)
Mon, Sep 14, 4:43 PM
Unknown Object (File)
Mon, Sep 14, 12:25 AM
Unknown Object (File)
Sun, Sep 13, 8:35 AM
Unknown Object (File)
Sun, Sep 13, 12:46 AM
Unknown Object (File)
Sun, Sep 13, 12:46 AM
Unknown Object (File)
Sat, Sep 12, 1:07 PM

Details

Reviewers
markj
kevans
seuros
andrew
manu
Group Reviewers
csprng
Summary
The TPM 2.0 driver periodically contributes TPM-generated random bytes
to the kernel entropy pool, but the TPM 1.2 driver does not.

Issue TPM_GetRandom every ten seconds and submit successful responses
as RANDOM_PURE_TPM.  Keep each exchange under the TPM transaction lock.
Defer harvesting while the character device is open or a command is
pending so the task cannot consume a user response.  Drain the task for
suspend and detach, rearming it after resume or a failed suspend.

Document the expanded scope of RANDOM_ENABLE_TPM and update the kernel
configuration comments that described it as TPM 2.0-only.

Validated on a STMicroelectronics TPM 1.2 TIS device.  DTrace observed
periodic entropy submissions; a raw GetRandom response remained intact
while the device was held open across a harvest interval; and module
unload/reload deregistered and restored the entropy source cleanly.

MFC after:      2 weeks

Diff Detail

Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

Thanks for adding csprng. One thing that bears a bit of scrutiny here and the existing tpm20 collector is the registered quality level. https://trustedcomputinggroup.org/resource/sha-1-uses-in-tpm-v1-2/ claims the SHA-1 mixing function does not materially degrade the output and I can link some papers that claim they tend to outperform PRNGs. In a tpm20, you generally have a high(er) quality random source and mixing function, but it could also be a vTPM proxying CPU rdrand or the like.

Thanks for adding csprng. One thing that bears a bit of scrutiny here and the existing tpm20 collector is the registered quality level. https://trustedcomputinggroup.org/resource/sha-1-uses-in-tpm-v1-2/ claims the SHA-1 mixing function does not materially degrade the output and I can link some papers that claim they tend to outperform PRNGs. In a tpm20, you generally have a high(er) quality random source and mixing function, but it could also be a vTPM proxying CPU rdrand or the like.

FWIW- I think the change is largely fine, but the main thought I had when looking at it initially is that it might be worth having its own RANDOM_PURE_TPM12 just in case one wanted to disable just entropy from older chips in their own generic images. We only have something like 4 bits left for new sources at the moment, though, so that kind of needs more deliberation. OTOH, Fortuna's design (as I understand it) means that it doesn't really matter if this single source is lower quality as long as it's not completely broken.

FWIW- I think the change is largely fine, but the main thought I had when looking at it initially is that it might be worth having its own RANDOM_PURE_TPM12 just in case one wanted to disable just entropy from older chips in their own generic images. We only have something like 4 bits left for new sources at the moment, though, so that kind of needs more deliberation. OTOH, Fortuna's design (as I understand it) means that it doesn't really matter if this single source is lower quality as long as it's not completely broken.

I tangentially agree but along the lines of dropping PURE so both can be toggled. I am less inclined to burn an additional type bit on it given the remaining size you mention unless there is an easy way to extend that in the future (with main justification being a hw tpm12 can be a stronger entropy source than some tpm20 types, so the version isn't necessarily strong signal alone).

@kevans I've spent the interim thinking about this occasionally and I think the design is sound with consideration of the existing TPM2.0 harvester and we uncovered some framework decisions that deserve some new thought.

My current recommendation is we consider a followup to allow some of the RANDOM_PURE sources to be disabled. This helps your concern of a specialized system operator deciding to exclude any of these sources, including virtio-rng and maybe RDRAND, without burning a new type bit, and further I don't think it's realistic to have both TPM versions on a platform so policy decisions can be determined by the operator by platform.

There is a second more complicated followup that might redefine how these sources contribute to unblocking fortuna initially, i.e. vTPM is potentially a useful feeder once bootstrapped but we maybe shouldn't unblock based on it (... and right now that is purely theoretical, I noticed the TPM attaches fairly late and then only seeds a small amount every 10 seconds, so it is not a meaningful bootstrap contributor, which could be a later investigation). My thinking here is bootstrap credit may be a bit aggressive for unknown quality devices, but is fine once fortuna is bootstrapped given its properties, and a hardware TPM is potentially independent counterweight for CPU seeding if eventually we move it earlier and reconsider its contribution amount.

Of course I would welcome any discussion with experts on csprng, if you see any at the event maybe you can poke them and I am available to meet virtually.

How useful a source of entropy is this? Initial seeding is really the only hard and important part of Fortuna or other system CSPRNGs. The periodic additional mixing is nice, but no one's threat model depends on it. (I'm not opposed, though.)

I don't really understand the RANDOM_PURE discussion.

In D59239#1363827, @cem wrote:

How useful a source of entropy is this? Initial seeding is really the only hard and important part of Fortuna or other system CSPRNGs. The periodic additional mixing is nice, but no one's threat model depends on it. (I'm not opposed, though.)

HW TPMs are typically high quality sources. TPM is just an interface spec so there are ways to tilt that toward equality with CPU (a software vTPM backend that proxies RDRAND) or quality and diversity (TPM with TRNG) and you can't infer this from the interface version. Some ST and Infeneon TPM 1.2 have AIS-31 generators for example.

I don't really understand the RANDOM_PURE discussion.

It's a broad statement, so I'm not sure how to help yet. Kyle's concern is toggling these feeders and that is not currently possible for this tpm or the existing tpm20 feeder. My suggestion is to allow toggling. Perhaps IRC or somewhere to discuss?

Dtrace tells that it's harvesting fine:
CPU ID FUNCTION:NAME

3 101390                tpm_harvest:entry tpm_harvest
2  49401      random_harvest_queue_:entry random_harvest_queue_
2  49401      random_harvest_queue_:entry random_harvest_queue_
2 101390                tpm_harvest:entry tpm_harvest
1  49401      random_harvest_queue_:entry random_harvest_queue_
1  49401      random_harvest_queue_:entry random_harvest_queue_

(Tested on tpm: IFX SLB 9635 TT 1.2 rev 0x10)