From: Alexander Steffen <hidden> Date: 2017-08-31 17:19:14
The self test logic for TPM 2.0 was probably based on the implementation
for TPM 1.2, but did not correctly take into account some TPM 2.0 specifics.
This patch series fixes those issues.
v2:
- Moved implementation description from comment to commit message.
Alexander Steffen (3):
tpm2-cmd: Trigger only missing self tests
tpm2-cmd: Use dynamic delay to wait for self test result
tpm2-cmd: React correctly to RC_TESTING from self tests
drivers/char/tpm/tpm2-cmd.c | 69 +++++++++++++--------------------------------
1 file changed, 20 insertions(+), 49 deletions(-)
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Alexander Steffen <hidden> Date: 2017-08-31 17:19:11
In order to avoid delaying the code longer than necessary while still
giving the TPM enough time to execute the self tests asynchronously, start
with a small delay between two polls and increase it each round.
Signed-off-by: Alexander Steffen <redacted>
Reviewed-by: Jarkko Sakkinen <redacted>
---
drivers/char/tpm/tpm2-cmd.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
@@ -877,20 +877,17 @@ static int tpm2_start_selftest(struct tpm_chip *chip, bool full)staticinttpm2_do_selftest(structtpm_chip*chip){intrc;-unsignedintloops;-unsignedintdelay_msec=100;-unsignedlongduration;-inti;--duration=tpm2_calc_ordinal_duration(chip,TPM2_CC_SELF_TEST);+unsignedintdelay_msec=20;+longduration;-loops=jiffies_to_msecs(duration)/delay_msec;+duration=jiffies_to_msecs(+tpm2_calc_ordinal_duration(chip,TPM2_CC_SELF_TEST));rc=tpm2_start_selftest(chip,false);if(rc)returnrc;-for(i=0;i<loops;i++){+while(duration>0){/* Attempt to read a PCR value */rc=tpm2_pcr_read(chip,0,NULL);if(rc<0)
@@ -900,6 +897,10 @@ static int tpm2_do_selftest(struct tpm_chip *chip)break;tpm_msleep(delay_msec);+duration-=delay_msec;++/* wait longer the next round */+delay_msec*=2;}returnrc;
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info@ http://vger.kernel.org/majordomo-info.html
From: Alexander Steffen <hidden> Date: 2017-08-31 17:19:13
tpm2_do_selftest is only used during initialization of the TPM to ensure
that the device functions correctly. Therefore, it is sufficient to request
only missing self tests (parameter full_test=0), not a reexecution of all
self tests, as was done before. This allows for a faster execution of this
command.
Signed-off-by: Alexander Steffen <redacted>
Reviewed-by: Jarkko Sakkinen <redacted>
---
drivers/char/tpm/tpm2-cmd.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
@@ -886,7 +886,7 @@ static int tpm2_do_selftest(struct tpm_chip *chip)loops=jiffies_to_msecs(duration)/delay_msec;-rc=tpm2_start_selftest(chip,true);+rc=tpm2_start_selftest(chip,false);if(rc)returnrc;
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Alexander Steffen <hidden> Date: 2017-08-31 17:19:16
The TPM can choose one of two ways to react to the TPM2_SelfTest command.
It can either run all self tests synchronously and then return RC_SUCCESS
once all tests were successful. Or it can choose to run the tests
asynchronously and return RC_TESTING immediately while the self tests still
execute in the background.
The previous implementation apparently was not aware of those possibilities
and attributed RC_TESTING to some prototype chips instead. With this change
the return code of TPM2_SelfTest is interpreted correctly, i.e. the self
test result is polled if and only if RC_TESTING is received.
Unfortunately, the polling cannot be done in the most straightforward way.
If RC_TESTING is received, ideally the code should now poll the
selfTestDone bit in the STS register, as this avoids sending more commands,
that might interrupt self tests executing in the background and thus
prevent them from ever completing. But it cannot be guaranteed that this
bit is correctly implemented for all devices, so the next best thing would
be to use TPM2_GetTestResult to query the test result. But the response to
that command can be very long, and the code currently lacks the
capabilities for efficient unmarshalling, so it is difficult to execute
this command.
Therefore, we simply run the TPM2_SelfTest command in a loop, which should
complete eventually, since we only request the execution of self tests that
have not yet been done.
Signed-off-by: Alexander Steffen <redacted>
Reviewed-by: Jarkko Sakkinen <redacted>
---
drivers/char/tpm/tpm2-cmd.c | 52 ++++++++++-----------------------------------
1 file changed, 11 insertions(+), 41 deletions(-)
@@ -834,64 +834,34 @@ static const struct tpm_input_header tpm2_selftest_header = {};/**-*tpm2_continue_selftest()-startaselftest-*-*@chip:TPMchiptouse-*@full:testallcommandsinsteadoftestingonlythosethatwerenot-*previouslytested.-*-*Return:Sameaswithtpm_transmit_cmdwithexceptionofRC_TESTING.-*/-staticinttpm2_start_selftest(structtpm_chip*chip,boolfull)-{-intrc;-structtpm2_cmdcmd;--cmd.header.in=tpm2_selftest_header;-cmd.params.selftest_in.full_test=full;--rc=tpm_transmit_cmd(chip,NULL,&cmd,TPM2_SELF_TEST_IN_SIZE,0,0,-"continue selftest");--/* At least some prototype chips seem to give RC_TESTING error-*immediately.Thisisaworkaroundforthat.-*/-if(rc==TPM2_RC_TESTING){-dev_warn(&chip->dev,"Got RC_TESTING, ignoring\n");-rc=0;-}--returnrc;-}--/***tpm2_do_selftest()-ensurethatallselftestshavepassed**@chip:TPMchiptouse**Return:Sameaswithtpm_transmit_cmd.*-*DuringtheselftestTPM2commandsreturnwiththeerrorcodeRC_TESTING.-*WaitingisdonebyissuingPCRreaduntilitexecutessuccessfully.+*TheTPMcaneitherrunallselftestssynchronouslyandthenreturn+*RC_SUCCESSoncealltestsweresuccessful.Oritcanchoosetorunthetests+*asynchronouslyandreturnRC_TESTINGimmediatelywhiletheselftestsstill+*executeinthebackground.Thisfunctionhandlesbothcasesandwaitsuntil+*alltestshavecompleted.*/staticinttpm2_do_selftest(structtpm_chip*chip){intrc;unsignedintdelay_msec=20;longduration;+structtpm2_cmdcmd;duration=jiffies_to_msecs(tpm2_calc_ordinal_duration(chip,TPM2_CC_SELF_TEST));-rc=tpm2_start_selftest(chip,false);-if(rc)-returnrc;-while(duration>0){-/* Attempt to read a PCR value */-rc=tpm2_pcr_read(chip,0,NULL);-if(rc<0)-break;+cmd.header.in=tpm2_selftest_header;+cmd.params.selftest_in.full_test=0;++rc=tpm_transmit_cmd(chip,NULL,&cmd,TPM2_SELF_TEST_IN_SIZE,+0,0,"continue selftest");if(rc!=TPM2_RC_TESTING)break;
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info@ http://vger.kernel.org/majordomo-info.html
From: Jarkko Sakkinen <hidden> Date: 2017-09-02 10:16:49
On Thu, Aug 31, 2017 at 07:18:55PM +0200, Alexander Steffen wrote:
The self test logic for TPM 2.0 was probably based on the implementation
for TPM 1.2, but did not correctly take into account some TPM 2.0 specifics.
This patch series fixes those issues.
v2:
- Moved implementation description from comment to commit message.
Alexander Steffen (3):
tpm2-cmd: Trigger only missing self tests
tpm2-cmd: Use dynamic delay to wait for self test result
tpm2-cmd: React correctly to RC_TESTING from self tests
drivers/char/tpm/tpm2-cmd.c | 69 +++++++++++++--------------------------------
1 file changed, 20 insertions(+), 49 deletions(-)
--
2.7.4
Great, just have to test these.
/Jarkko
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Jarkko Sakkinen <hidden> Date: 2017-09-06 12:57:46
On Thu, Aug 31, 2017 at 07:18:55PM +0200, Alexander Steffen wrote:
The self test logic for TPM 2.0 was probably based on the implementation
for TPM 1.2, but did not correctly take into account some TPM 2.0 specifics.
This patch series fixes those issues.
v2:
- Moved implementation description from comment to commit message.
Alexander Steffen (3):
tpm2-cmd: Trigger only missing self tests
tpm2-cmd: Use dynamic delay to wait for self test result
tpm2-cmd: React correctly to RC_TESTING from self tests
drivers/char/tpm/tpm2-cmd.c | 69 +++++++++++++--------------------------------
1 file changed, 20 insertions(+), 49 deletions(-)
--
2.7.4
Applied to my master for convenient testing.
/Jarkko
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Jarkko Sakkinen <hidden> Date: 2017-09-08 10:00:34
On Wed, Sep 06, 2017 at 03:57:40PM +0300, Jarkko Sakkinen wrote:
On Thu, Aug 31, 2017 at 07:18:55PM +0200, Alexander Steffen wrote:
quoted
The self test logic for TPM 2.0 was probably based on the implementation
for TPM 1.2, but did not correctly take into account some TPM 2.0 specifics.
This patch series fixes those issues.
v2:
- Moved implementation description from comment to commit message.
Alexander Steffen (3):
tpm2-cmd: Trigger only missing self tests
tpm2-cmd: Use dynamic delay to wait for self test result
tpm2-cmd: React correctly to RC_TESTING from self tests
drivers/char/tpm/tpm2-cmd.c | 69 +++++++++++++--------------------------------
1 file changed, 20 insertions(+), 49 deletions(-)
--
2.7.4
Applied to my master for convenient testing.
/Jarkko
Tested-by: Jarkko Sakkinen <redacted>
/Jarkko
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html