1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
#!/usr/bin/python
# Copyright 2015 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Module for testing hash functions using extended commands."""
from __future__ import print_function
import hashlib
import struct
import subcmd
import utils
# Hash command modes
CMD_START = 0
CMD_CONT = 1
CMD_FINISH = 2
CMD_SINGLE = 3
# Hash modes
MODE_SHA1 = 0
MODE_SHA256 = 1
# A standard empty response to HASH extended commands.
EMPTY_RESPONSE = ''.join('%c' % x for x in (0x80, 0x01, 0x00, 0x00, 0x00, 0x0c,
0xba, 0xcc, 0xd0, 0x0a, 0x00, 0x01))
test_inputs = (
# SHA mode cmd mode handle text
(MODE_SHA1, 'single', 0, 'anything really will work here'),
(MODE_SHA256, 'single', 0, 'some more text, this time for sha256'),
(MODE_SHA256, 'start', 1, 'some more text, this time for sha256'),
(MODE_SHA256, 'cont', 1, 'some more text, this time for sha256'),
(MODE_SHA256, 'start', 2, 'this could be anything, we just need to'),
(MODE_SHA1, 'single', 3, 'interleave a SHA1 single calculation'),
(MODE_SHA256, 'single', 3, 'interleave a SHA256 single calculation'),
(MODE_SHA1, 'start', 3, 'let\'s interleave a sha1 calculation'),
(MODE_SHA256, 'cont', 2, 'fill up a second context with something'),
(MODE_SHA256, 'cont', 1, 'let\'s feed some more into context 1'),
(MODE_SHA256, 'finish', 1, 'some more text, this time for sha256'),
(MODE_SHA1, 'cont', 3, 'with two active sha256 calculations'),
(MODE_SHA1, 'finish', 3, 'this should be enough'),
(MODE_SHA256, 'finish', 2, 'it does not really matter what'),
)
def hash_test(tpm):
"""Exercise multiple hash threads simultaneously.
Command structure, shared out of band with the test running on the target:
field | size | note
===================================================================
hash_cmd | 1 | 0 - start, 1 - cont., 2 - finish, 4 - single
hash_mode | 1 | 0 - sha1, 1 - sha256
handle | 1 | session handle, ignored in 'single' mode
text_len | 2 | size of the text to process, big endian
text | text_len | text to hash
Args:
tpm: a tpm object used to communicate with the device
Raises:
subcmd.TpmTestError: on unexpected target responses
"""
contexts = {}
function_map = {
MODE_SHA1: ('sha1', hashlib.sha1),
MODE_SHA256: ('sha256', hashlib.sha256)
}
cmd_map = {
'start': CMD_START,
'cont': CMD_CONT,
'finish': CMD_FINISH,
'single': CMD_SINGLE
}
for test in test_inputs:
hash_mode, cmd_name, handle, text = test
mode_name, hash_func = function_map[hash_mode]
hash_cmd = cmd_map[cmd_name]
test_name = '%s:%s:%d' % (mode_name, cmd_name, handle)
cmd = '%c' % hash_cmd
cmd += '%c' % hash_mode
cmd += '%c' % handle # Ignored for single shots
cmd += struct.pack('>H', len(text))
cmd += text
wrapped_response = tpm.command(tpm.wrap_ext_command(subcmd.HASH, cmd))
if hash_cmd in (CMD_START, CMD_CONT):
if hash_cmd == CMD_START:
contexts[handle] = hash_func()
h = contexts[handle]
h.update(text)
if wrapped_response != EMPTY_RESPONSE:
raise subcmd.TpmTestError("Unexpected response to '%s': %s" %
(test_name, utils.hex_dump(wrapped_response)))
continue
if hash_cmd == CMD_FINISH:
h = contexts[handle]
elif hash_cmd == CMD_SINGLE:
h = hash_func()
else:
raise subcmd.TpmTestError('Unknown command %d' % hash_cmd)
h.update(text)
digest = h.digest()
result = wrapped_response[12:]
if result != h.digest():
raise subcmd.TpmTestError('%s error:%s%s' % (test_name,
utils.hex_dump(digest),
utils.hex_dump(result)))
print('%sSUCCESS: %s' % (utils.cursor_back(), test_name))
|