diff options
-rw-r--r-- | test/tpm_test/hash_test.py | 118 | ||||
-rwxr-xr-x | test/tpm_test/tpmtest.py | 4 |
2 files changed, 121 insertions, 1 deletions
diff --git a/test/tpm_test/hash_test.py b/test/tpm_test/hash_test.py new file mode 100644 index 0000000000..c1cdddbbe5 --- /dev/null +++ b/test/tpm_test/hash_test.py @@ -0,0 +1,118 @@ +#!/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 utils + +HASH = 1 + +# Hash command modes +CMD_START = 0 +CMD_CONT = 1 +CMD_FINISH = 2 +CMD_SINGLE = 3 + +# Hash modes +MODE_SHA1 = 0 +MODE_SHA256 = 1 + + +class HashError(Exception): + pass + +# 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, '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: + HashError: 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(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 HashError("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 HashError('Unknown command %d' % hash_cmd) + h.update(text) + digest = h.digest() + result = wrapped_response[12:] + if result != h.digest(): + raise HashError('%s error:%s%s' % (test_name, + utils.hex_dump(digest), + utils.hex_dump(result))) + print('%sSUCCESS: %s' % (utils.cursor_back(), test_name)) diff --git a/test/tpm_test/tpmtest.py b/test/tpm_test/tpmtest.py index fe866f3665..571a4548d9 100755 --- a/test/tpm_test/tpmtest.py +++ b/test/tpm_test/tpmtest.py @@ -19,6 +19,7 @@ root_dir = os.path.dirname(os.path.abspath(sys.argv[0])) sys.path.append(os.path.join(root_dir, '..', '..', 'build', 'tpm_test')) import crypto_test +import hash_test import ftdi_spi_tpm # Extension command for dcypto testing @@ -131,7 +132,8 @@ if __name__ == '__main__': t = TPM(debug_mode=debug_needed) crypto_test.crypto_tests(t, os.path.join(root_dir, 'crypto_test.xml')) - except (TpmError, crypto_test.CryptoError) as e: + hash_test.hash_test(t) + except (TpmError, crypto_test.CryptoError, hash_test.HashError) as e: print() print('Error:', e) if debug_needed: |