diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2015-11-27 07:32:34 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2015-12-03 02:21:19 -0800 |
commit | 898e16bf7b7726b7112b260e5f6734822a6489b0 (patch) | |
tree | a1adafef738cab333914930323acd2c2b5e4ec3a | |
parent | e1be8e179cf9f5e5e7e097bd081a0d92590a2a6f (diff) | |
download | chrome-ec-898e16bf7b7726b7112b260e5f6734822a6489b0.tar.gz |
cr50: test: add hash testing host side implementation
The new module generates hash test extension subcommands, driven by
the 'test_inputs' table.
Each table entry is a tuple, including the test name and the data to
be hashed. The test name determines the hash type (sha1 or sha256) and
the test mode (single or spread over several messages). The last
element of the name is the context number (ignored in single message
mode).
The hash extended command payload looks as follows:
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
BRANCH=none
BUG=chrome-os-partner:43025
TEST=currently failing, a couple of hash code tweaks needed, see
upcoming patches.
Change-Id: Ie992bf01cae3c5278110357b482370b2fc11c70f
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/314693
Reviewed-by: Randall Spangler <rspangler@chromium.org>
-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: |