Page MenuHomeFreeBSD

tpm: fix tpmtis support for ST33KTPM2X32CKE3
ClosedPublic

Authored by olivier on Thu, Jun 25, 11:28 AM.

Details

Summary

Patch from Benoit Sansoni <benoit.sansoni@gmail.com> in https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=295103

The tpmtis driver fails to operate correctly with the STMicroelectronics ST33KTPM2X32CKE3 TPM2 chip.
After reading the response, the device must be explicitly transitioned back to the command-ready state before the locality is relinquished; otherwise subsequent commands fail.

Write TPM_STS_CMD_RDY to the TPM_STS register (with a write barrier) at the end of tpmtis_transmit(), before relinquishing the locality.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

olivier created this revision.
dev/tpm/tpm_tis_core.c
134 ↗(On Diff #180613)

No objection to keeping this, but it should probably be under if (bootverbose) -- I see you already clocked the other style problems here in the PR

482 ↗(On Diff #180613)

I'll check the spec again here later today... if we're just out of spec entirely, we can drop the comment

From TCG PC Client Specific TPM Interface
Specification (TIS) version 1.3, 5.6.12 "Status Register":

The TPM_STS_x commandReady field is functionally overloaded. If there is no command
being executed, a write to this field is an indicator to the TPM that it must prepare to
receive a command. If there is a command being executed, a write to this field serves as an
abort of that command. If a command has completed and the results have been read, a
write to this field allows the TPM to free internal resources (including the Read and Write
FIFOs) and proceed with background or other processes allowed during idle time. A TPM
may be designed in a manner that allows the first write to this field to clear and free the
TPM’s resources and make it ready to receive a command.

Software must be prepared to send two writes of a “1” to this field: the first to indicate
successful read of all the data, thus clearing the data from the ReadFIFO and freeing the
TPM’s resources, and the second to indicate to the TPM it is about to send a new command.
The time between receiving the data from a command and sending the first write to this
field should be very short to allow TPMs that perform background processing to proceed.
The time between the first write and the second indicates the beginning of a new command
is arbitrary.

Software may be written such that the second write to this field is only necessary if the TPM
does not respond with a ready after the first write. In this case, the software, after writing a
“1” to this field indicating the receipt of the data, may query this field. If the TPM sets this
field to a “1” indicating its readiness to receive a command, the software may proceed to
send the command without writing a “1” to this field.

Emphasis on the second paragraph: so this is necessary to allow the TPM to free up resources, and I guess the omission completely breaks the chip they're looking at. We should spell it the same as it's written in tpmtis_go_ready, though, just without the wait+timeout because we don't need to observe any particular state transition.

olivier marked 2 inline comments as done.
This revision is now accepted and ready to land.Fri, Jun 26, 6:58 PM