1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
3 from argparse
import ArgumentParser
4 from argparse
import FileType
8 from tpm2
import ProtocolError
13 class SmokeTest(unittest
.TestCase
):
15 self
.client
= tpm2
.Client()
16 self
.root_key
= self
.client
.create_root_key()
19 self
.client
.flush_context(self
.root_key
)
22 def test_seal_with_auth(self
):
23 data
= ('X' * 64).encode()
24 auth
= ('A' * 15).encode()
26 blob
= self
.client
.seal(self
.root_key
, data
, auth
, None)
27 result
= self
.client
.unseal(self
.root_key
, blob
, auth
, None)
28 self
.assertEqual(data
, result
)
30 def test_seal_with_policy(self
):
31 handle
= self
.client
.start_auth_session(tpm2
.TPM2_SE_TRIAL
)
33 data
= ('X' * 64).encode()
34 auth
= ('A' * 15).encode()
38 self
.client
.policy_pcr(handle
, pcrs
)
39 self
.client
.policy_password(handle
)
41 policy_dig
= self
.client
.get_policy_digest(handle
)
43 self
.client
.flush_context(handle
)
45 blob
= self
.client
.seal(self
.root_key
, data
, auth
, policy_dig
)
47 handle
= self
.client
.start_auth_session(tpm2
.TPM2_SE_POLICY
)
50 self
.client
.policy_pcr(handle
, pcrs
)
51 self
.client
.policy_password(handle
)
53 result
= self
.client
.unseal(self
.root_key
, blob
, auth
, handle
)
55 self
.client
.flush_context(handle
)
58 self
.assertEqual(data
, result
)
60 def test_unseal_with_wrong_auth(self
):
61 data
= ('X' * 64).encode()
62 auth
= ('A' * 20).encode()
65 blob
= self
.client
.seal(self
.root_key
, data
, auth
, None)
67 result
= self
.client
.unseal(self
.root_key
, blob
,
68 auth
[:-1] + 'B'.encode(), None)
69 except ProtocolError
as e
:
72 self
.assertEqual(rc
, tpm2
.TPM2_RC_AUTH_FAIL
)
74 def test_unseal_with_wrong_policy(self
):
75 handle
= self
.client
.start_auth_session(tpm2
.TPM2_SE_TRIAL
)
77 data
= ('X' * 64).encode()
78 auth
= ('A' * 17).encode()
82 self
.client
.policy_pcr(handle
, pcrs
)
83 self
.client
.policy_password(handle
)
85 policy_dig
= self
.client
.get_policy_digest(handle
)
87 self
.client
.flush_context(handle
)
89 blob
= self
.client
.seal(self
.root_key
, data
, auth
, policy_dig
)
91 # Extend first a PCR that is not part of the policy and try to unseal.
92 # This should succeed.
94 ds
= tpm2
.get_digest_size(tpm2
.TPM2_ALG_SHA1
)
95 self
.client
.extend_pcr(1, ('X' * ds
).encode())
97 handle
= self
.client
.start_auth_session(tpm2
.TPM2_SE_POLICY
)
100 self
.client
.policy_pcr(handle
, pcrs
)
101 self
.client
.policy_password(handle
)
103 result
= self
.client
.unseal(self
.root_key
, blob
, auth
, handle
)
105 self
.client
.flush_context(handle
)
108 self
.assertEqual(data
, result
)
110 # Then, extend a PCR that is part of the policy and try to unseal.
112 self
.client
.extend_pcr(16, ('X' * ds
).encode())
114 handle
= self
.client
.start_auth_session(tpm2
.TPM2_SE_POLICY
)
119 self
.client
.policy_pcr(handle
, pcrs
)
120 self
.client
.policy_password(handle
)
122 result
= self
.client
.unseal(self
.root_key
, blob
, auth
, handle
)
123 except ProtocolError
as e
:
125 self
.client
.flush_context(handle
)
127 self
.client
.flush_context(handle
)
130 self
.assertEqual(rc
, tpm2
.TPM2_RC_POLICY_FAIL
)
132 def test_seal_with_too_long_auth(self
):
133 ds
= tpm2
.get_digest_size(tpm2
.TPM2_ALG_SHA1
)
134 data
= ('X' * 64).encode()
135 auth
= ('A' * (ds
+ 1)).encode()
139 blob
= self
.client
.seal(self
.root_key
, data
, auth
, None)
140 except ProtocolError
as e
:
143 self
.assertEqual(rc
, tpm2
.TPM2_RC_SIZE
)
145 def test_too_short_cmd(self
):
149 cmd
= struct
.pack(fmt
,
150 tpm2
.TPM2_ST_NO_SESSIONS
,
151 struct
.calcsize(fmt
) + 1,
152 tpm2
.TPM2_CC_FLUSH_CONTEXT
,
155 self
.client
.send_cmd(cmd
)
160 self
.assertEqual(rejected
, True)
162 def test_read_partial_resp(self
):
165 cmd
= struct
.pack(fmt
,
166 tpm2
.TPM2_ST_NO_SESSIONS
,
167 struct
.calcsize(fmt
),
168 tpm2
.TPM2_CC_GET_RANDOM
,
170 self
.client
.tpm
.write(cmd
)
171 hdr
= self
.client
.tpm
.read(10)
172 sz
= struct
.unpack('>I', hdr
[2:6])[0]
173 rsp
= self
.client
.tpm
.read()
176 self
.assertEqual(sz
, 10 + 2 + 32)
177 self
.assertEqual(len(rsp
), 2 + 32)
179 def test_read_partial_overwrite(self
):
182 cmd
= struct
.pack(fmt
,
183 tpm2
.TPM2_ST_NO_SESSIONS
,
184 struct
.calcsize(fmt
),
185 tpm2
.TPM2_CC_GET_RANDOM
,
187 self
.client
.tpm
.write(cmd
)
188 # Read part of the respone
189 rsp1
= self
.client
.tpm
.read(15)
192 self
.client
.tpm
.write(cmd
)
194 # Read the whole respone
195 rsp2
= self
.client
.tpm
.read()
198 self
.assertEqual(len(rsp1
), 15)
199 self
.assertEqual(len(rsp2
), 10 + 2 + 32)
201 def test_send_two_cmds(self
):
205 cmd
= struct
.pack(fmt
,
206 tpm2
.TPM2_ST_NO_SESSIONS
,
207 struct
.calcsize(fmt
),
208 tpm2
.TPM2_CC_GET_RANDOM
,
210 self
.client
.tpm
.write(cmd
)
212 # expect the second one to raise -EBUSY error
213 self
.client
.tpm
.write(cmd
)
214 rsp
= self
.client
.tpm
.read()
218 rsp
= self
.client
.tpm
.read()
223 self
.assertEqual(rejected
, True)
225 class SpaceTest(unittest
.TestCase
):
227 logging
.basicConfig(filename
='SpaceTest.log', level
=logging
.DEBUG
)
229 def test_make_two_spaces(self
):
230 log
= logging
.getLogger(__name__
)
231 log
.debug("test_make_two_spaces")
233 space1
= tpm2
.Client(tpm2
.Client
.FLAG_SPACE
)
234 root1
= space1
.create_root_key()
235 space2
= tpm2
.Client(tpm2
.Client
.FLAG_SPACE
)
236 root2
= space2
.create_root_key()
237 root3
= space2
.create_root_key()
239 log
.debug("%08x" % (root1
))
240 log
.debug("%08x" % (root2
))
241 log
.debug("%08x" % (root3
))
243 def test_flush_context(self
):
244 log
= logging
.getLogger(__name__
)
245 log
.debug("test_flush_context")
247 space1
= tpm2
.Client(tpm2
.Client
.FLAG_SPACE
)
248 root1
= space1
.create_root_key()
249 log
.debug("%08x" % (root1
))
251 space1
.flush_context(root1
)
253 def test_get_handles(self
):
254 log
= logging
.getLogger(__name__
)
255 log
.debug("test_get_handles")
257 space1
= tpm2
.Client(tpm2
.Client
.FLAG_SPACE
)
258 space1
.create_root_key()
259 space2
= tpm2
.Client(tpm2
.Client
.FLAG_SPACE
)
260 space2
.create_root_key()
261 space2
.create_root_key()
263 handles
= space2
.get_cap(tpm2
.TPM2_CAP_HANDLES
, tpm2
.HR_TRANSIENT
)
265 self
.assertEqual(len(handles
), 2)
267 log
.debug("%08x" % (handles
[0]))
268 log
.debug("%08x" % (handles
[1]))
270 def test_invalid_cc(self
):
271 log
= logging
.getLogger(__name__
)
272 log
.debug(sys
._getframe
().f_code
.co_name
)
274 TPM2_CC_INVALID
= tpm2
.TPM2_CC_FIRST
- 1
276 space1
= tpm2
.Client(tpm2
.Client
.FLAG_SPACE
)
277 root1
= space1
.create_root_key()
278 log
.debug("%08x" % (root1
))
281 cmd
= struct
.pack(fmt
, tpm2
.TPM2_ST_NO_SESSIONS
, struct
.calcsize(fmt
),
287 except ProtocolError
as e
:
290 self
.assertEqual(rc
, tpm2
.TPM2_RC_COMMAND_CODE |
291 tpm2
.TSS2_RESMGR_TPM_RC_LAYER
)
293 class AsyncTest(unittest
.TestCase
):
295 logging
.basicConfig(filename
='AsyncTest.log', level
=logging
.DEBUG
)
297 def test_async(self
):
298 log
= logging
.getLogger(__name__
)
299 log
.debug(sys
._getframe
().f_code
.co_name
)
301 async_client
= tpm2
.Client(tpm2
.Client
.FLAG_NONBLOCK
)
302 log
.debug("Calling get_cap in a NON_BLOCKING mode")
303 async_client
.get_cap(tpm2
.TPM2_CAP_HANDLES
, tpm2
.HR_LOADED_SESSION
)