summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2015-11-27 07:32:34 -0800
committerchrome-bot <chrome-bot@chromium.org>2015-12-03 02:21:19 -0800
commit898e16bf7b7726b7112b260e5f6734822a6489b0 (patch)
treea1adafef738cab333914930323acd2c2b5e4ec3a
parente1be8e179cf9f5e5e7e097bd081a0d92590a2a6f (diff)
downloadchrome-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.py118
-rwxr-xr-xtest/tpm_test/tpmtest.py4
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: