Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests: tpm2: Determine available PCR bank

Determine an available PCR bank to be used by a test case by querying the
capability TPM2_GET_CAP. The TPM2 returns TPML_PCR_SELECTIONS that
contains an array of TPMS_PCR_SELECTIONs indicating available PCR banks
and the bitmasks that show which PCRs are enabled in each bank. Collect
the data in a dictionary. From the dictionary determine the PCR bank that
has the PCRs enabled that the test needs. This avoids test failures with
TPM2's that either to not have a SHA-1 bank or whose SHA-1 bank is
disabled.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Tested-by: Jarkko Sakkinen <jarkko@kernel.org>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>

authored by

Stefan Berger and committed by
Jarkko Sakkinen
0d060f23 ea4424be

+52 -8
+31
tools/testing/selftests/tpm2/tpm2.py
··· 56 56 57 57 TPM2_CAP_HANDLES = 0x00000001 58 58 TPM2_CAP_COMMANDS = 0x00000002 59 + TPM2_CAP_PCRS = 0x00000005 59 60 TPM2_CAP_TPM_PROPERTIES = 0x00000006 60 61 61 62 TPM2_PT_FIXED = 0x100 ··· 713 712 pt += 1 714 713 715 714 return handles 715 + 716 + def get_cap_pcrs(self): 717 + pcr_banks = {} 718 + 719 + fmt = '>HII III' 720 + 721 + cmd = struct.pack(fmt, 722 + TPM2_ST_NO_SESSIONS, 723 + struct.calcsize(fmt), 724 + TPM2_CC_GET_CAPABILITY, 725 + TPM2_CAP_PCRS, 0, 1) 726 + rsp = self.send_cmd(cmd)[10:] 727 + _, _, cnt = struct.unpack('>BII', rsp[:9]) 728 + rsp = rsp[9:] 729 + 730 + # items are TPMS_PCR_SELECTION's 731 + for i in range(0, cnt): 732 + hash, sizeOfSelect = struct.unpack('>HB', rsp[:3]) 733 + rsp = rsp[3:] 734 + 735 + pcrSelect = 0 736 + if sizeOfSelect > 0: 737 + pcrSelect, = struct.unpack('%ds' % sizeOfSelect, 738 + rsp[:sizeOfSelect]) 739 + rsp = rsp[sizeOfSelect:] 740 + pcrSelect = int.from_bytes(pcrSelect, byteorder='big') 741 + 742 + pcr_banks[hash] = pcrSelect 743 + 744 + return pcr_banks
+21 -8
tools/testing/selftests/tpm2/tpm2_tests.py
··· 27 27 result = self.client.unseal(self.root_key, blob, auth, None) 28 28 self.assertEqual(data, result) 29 29 30 + def determine_bank_alg(self, mask): 31 + pcr_banks = self.client.get_cap_pcrs() 32 + for bank_alg, pcrSelection in pcr_banks.items(): 33 + if pcrSelection & mask == mask: 34 + return bank_alg 35 + return None 36 + 30 37 def test_seal_with_policy(self): 38 + bank_alg = self.determine_bank_alg(1 << 16) 39 + self.assertIsNotNone(bank_alg) 40 + 31 41 handle = self.client.start_auth_session(tpm2.TPM2_SE_TRIAL) 32 42 33 43 data = ('X' * 64).encode() ··· 45 35 pcrs = [16] 46 36 47 37 try: 48 - self.client.policy_pcr(handle, pcrs) 38 + self.client.policy_pcr(handle, pcrs, bank_alg=bank_alg) 49 39 self.client.policy_password(handle) 50 40 51 41 policy_dig = self.client.get_policy_digest(handle) ··· 57 47 handle = self.client.start_auth_session(tpm2.TPM2_SE_POLICY) 58 48 59 49 try: 60 - self.client.policy_pcr(handle, pcrs) 50 + self.client.policy_pcr(handle, pcrs, bank_alg=bank_alg) 61 51 self.client.policy_password(handle) 62 52 63 53 result = self.client.unseal(self.root_key, blob, auth, handle) ··· 82 72 self.assertEqual(rc, tpm2.TPM2_RC_AUTH_FAIL) 83 73 84 74 def test_unseal_with_wrong_policy(self): 75 + bank_alg = self.determine_bank_alg(1 << 16 | 1 << 1) 76 + self.assertIsNotNone(bank_alg) 77 + 85 78 handle = self.client.start_auth_session(tpm2.TPM2_SE_TRIAL) 86 79 87 80 data = ('X' * 64).encode() ··· 92 79 pcrs = [16] 93 80 94 81 try: 95 - self.client.policy_pcr(handle, pcrs) 82 + self.client.policy_pcr(handle, pcrs, bank_alg=bank_alg) 96 83 self.client.policy_password(handle) 97 84 98 85 policy_dig = self.client.get_policy_digest(handle) ··· 104 91 # Extend first a PCR that is not part of the policy and try to unseal. 105 92 # This should succeed. 106 93 107 - ds = tpm2.get_digest_size(tpm2.TPM2_ALG_SHA1) 108 - self.client.extend_pcr(1, ('X' * ds).encode()) 94 + ds = tpm2.get_digest_size(bank_alg) 95 + self.client.extend_pcr(1, ('X' * ds).encode(), bank_alg=bank_alg) 109 96 110 97 handle = self.client.start_auth_session(tpm2.TPM2_SE_POLICY) 111 98 112 99 try: 113 - self.client.policy_pcr(handle, pcrs) 100 + self.client.policy_pcr(handle, pcrs, bank_alg=bank_alg) 114 101 self.client.policy_password(handle) 115 102 116 103 result = self.client.unseal(self.root_key, blob, auth, handle) ··· 122 109 123 110 # Then, extend a PCR that is part of the policy and try to unseal. 124 111 # This should fail. 125 - self.client.extend_pcr(16, ('X' * ds).encode()) 112 + self.client.extend_pcr(16, ('X' * ds).encode(), bank_alg=bank_alg) 126 113 127 114 handle = self.client.start_auth_session(tpm2.TPM2_SE_POLICY) 128 115 129 116 rc = 0 130 117 131 118 try: 132 - self.client.policy_pcr(handle, pcrs) 119 + self.client.policy_pcr(handle, pcrs, bank_alg=bank_alg) 133 120 self.client.policy_password(handle) 134 121 135 122 result = self.client.unseal(self.root_key, blob, auth, handle)