aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/sw/hash_tester.py204
1 files changed, 168 insertions, 36 deletions
diff --git a/src/sw/hash_tester.py b/src/sw/hash_tester.py
index 1d8d5b0..2ca0aab 100755
--- a/src/sw/hash_tester.py
+++ b/src/sw/hash_tester.py
@@ -5,9 +5,9 @@
# hash_tester.py
# --------------
# This program sends several commands to the coretest_hashed subsystem
-# in order to verify the SHA-1 and SHA-256 hash function cores.
-# The program uses the built in hash implementations in Python
-# to do functional comparison and validation.
+# in order to verify the SHA-1, SHA-256 and SHA-512/x hash function
+# cores. The program will use the built in hash implementations in
+# Python to do functional comparison and validation.
#
# Note: This program requires the PySerial module.
# http://pyserial.sourceforge.net/
@@ -18,7 +18,7 @@
#
#
# Author: Joachim Strömbergson
-# Copyright (c) 2014, SUNET
+# Copyright (c) 2014, Secworks Sweden AB
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
@@ -72,8 +72,9 @@ STOP_BITS = 1
# Verbose operation on/off
VERBOSE = False
-# Delay time we wait
-DELAY_TIME = 0.05
+# Delay times we wait
+PROC_DELAY_TIME = 0.05
+COMM_DELAY_TIME = 0.05
# Memory map.
SOC = '\x55'
@@ -279,22 +280,22 @@ NIST_512_SINGLE = ['\x61', '\x62', '\x63', '\x80', '\x00', '\x00', '\x00', '\x00
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x18']
NIST_512_DOUBLE0 = ['\x61', '\x62', '\x63', '\x64', '\x62', '\x63', '\x64', '\x65',
- '\x63', '\x64', '\x65', '\x66', '\x64', '\x65', '\x66', '\x67',
- '\x65', '\x66', '\x67', '\x68', '\x66', '\x67', '\x68', '\x69',
- '\x67', '\x68', '\x69', '\x6A', '\x68', '\x69', '\x6A', '\x6B',
- '\x69', '\x6A', '\x6B', '\x6C', '\x6A', '\x6B', '\x6C', '\x6D',
- '\x6B', '\x6C', '\x6D', '\x6E', '\x6C', '\x6D', '\x6E', '\x6F',
- '\x6D', '\x6E', '\x6F', '\x70', '\x6E', '\x6F', '\x70', '\x71',
- '\x80', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00']
+ '\x63', '\x64', '\x65', '\x66', '\x64', '\x65', '\x66', '\x67',
+ '\x65', '\x66', '\x67', '\x68', '\x66', '\x67', '\x68', '\x69',
+ '\x67', '\x68', '\x69', '\x6A', '\x68', '\x69', '\x6A', '\x6B',
+ '\x69', '\x6A', '\x6B', '\x6C', '\x6A', '\x6B', '\x6C', '\x6D',
+ '\x6B', '\x6C', '\x6D', '\x6E', '\x6C', '\x6D', '\x6E', '\x6F',
+ '\x6D', '\x6E', '\x6F', '\x70', '\x6E', '\x6F', '\x70', '\x71',
+ '\x80', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00']
NIST_512_DOUBLE1 = ['\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
- '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
- '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
- '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
- '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
- '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
- '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
- '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x01', '\xC0']
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x01', '\xC0']
NIST_1024_SINGLE = ['\x61', '\x62', '\x63', '\x80', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
@@ -313,6 +314,40 @@ NIST_1024_SINGLE = ['\x61', '\x62', '\x63', '\x80', '\x00', '\x00', '\x00', '\x0
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x18']
+NIST_1024_DOUBLE0 = ['\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68',
+ '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', '\x69',
+ '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', '\x69', '\x6a',
+ '\x64', '\x65', '\x66', '\x67', '\x68', '\x69', '\x6a', '\x6b',
+ '\x65', '\x66', '\x67', '\x68', '\x69', '\x6a', '\x6b', '\x6c',
+ '\x66', '\x67', '\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d',
+ '\x67', '\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e',
+ '\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f',
+ '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f', '\x70',
+ '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f', '\x70', '\x71',
+ '\x6b', '\x6c', '\x6d', '\x6e', '\x6f', '\x70', '\x71', '\x72',
+ '\x6c', '\x6d', '\x6e', '\x6f', '\x70', '\x71', '\x72', '\x73',
+ '\x6d', '\x6e', '\x6f', '\x70', '\x71', '\x72', '\x73', '\x74',
+ '\x6e', '\x6f', '\x70', '\x71', '\x72', '\x73', '\x74', '\x75',
+ '\x80', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00']
+
+NIST_1024_DOUBLE1 = ['\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
+ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x03', '\x80']
+
#-------------------------------------------------------------------
# print_response()
@@ -373,7 +408,7 @@ def read_serial_thread(serialport):
buffer = []
else:
print "No open device yet."
- time.sleep(DELAY_TIME)
+ time.sleep(COMM_DELAY_TIME)
#-------------------------------------------------------------------
@@ -389,7 +424,7 @@ def write_serial_bytes(tx_cmd, serialport):
serialport.write(tx_byte)
# Allow the device to complete the transaction.
- time.sleep(DELAY_TIME)
+ time.sleep(COMM_DELAY_TIME)
#-------------------------------------------------------------------
@@ -409,9 +444,58 @@ def single_block_test_sha512x(block, mode, ser):
mode_cmd = chr(ord(SHA512_CTRL_INIT_CMD) + (ord(mode) << SHA512_CTRL_MODE_LOW))
write_serial_bytes([SOC, WRITE_CMD, SHA512_ADDR_PREFIX, SHA512_ADDR_CTRL,
'\x00', '\x00', '\x00', mode_cmd, EOC], ser)
- time.sleep(DELAY_TIME)
+ time.sleep(PROC_DELAY_TIME)
+ write_serial_bytes([SOC, READ_CMD, SHA512_ADDR_PREFIX, SHA512_ADDR_STATUS, EOC], ser)
+
+ # Select the correct number of digest addresses to read.
+ if (mode == MODE_SHA_512_224):
+ mode_digest_addr = sha512_digest_addr[0 : 7]
+ elif (mode == MODE_SHA_512_256):
+ mode_digest_addr = sha512_digest_addr[0 : 8]
+ elif (mode == MODE_SHA_384):
+ mode_digest_addr = sha512_digest_addr[0 : 12]
+ elif (mode == MODE_SHA_512):
+ mode_digest_addr = sha512_digest_addr
+
+ # Extract the digest.
+ for digest_addr in mode_digest_addr:
+ message = [SOC, READ_CMD, SHA512_ADDR_PREFIX] + [digest_addr] + [EOC]
+ write_serial_bytes(message, ser)
+ print""
+
+
+#-------------------------------------------------------------------
+# dual_block_test_sha512x()
+#
+# Write a given block to SHA-512/x and perform single block
+# processing for the given mode.
+#-------------------------------------------------------------------
+def dual_block_test_sha512x(block0, block1, mode, ser):
+ # Write block0 to SHA-512.
+ for i in range(len(block0) / 4):
+ message = [SOC, WRITE_CMD, SHA512_ADDR_PREFIX,] + [sha512_block_addr[i]] +\
+ block0[(i * 4) : ((i * 4 ) + 4)] + [EOC]
+ write_serial_bytes(message, ser)
+
+ # Start initial block hashing, wait and check status.
+ mode_cmd = chr(ord(SHA512_CTRL_INIT_CMD) + (ord(mode) << SHA512_CTRL_MODE_LOW))
+ write_serial_bytes([SOC, WRITE_CMD, SHA512_ADDR_PREFIX, SHA512_ADDR_CTRL,
+ '\x00', '\x00', '\x00', mode_cmd, EOC], ser)
+ time.sleep(PROC_DELAY_TIME)
+ write_serial_bytes([SOC, READ_CMD, SHA512_ADDR_PREFIX, SHA512_ADDR_STATUS, EOC], ser)
+
+ # Write block1 to SHA-512.
+ for i in range(len(block1) / 4):
+ message = [SOC, WRITE_CMD, SHA512_ADDR_PREFIX,] + [sha512_block_addr[i]] +\
+ block1[(i * 4) : ((i * 4 ) + 4)] + [EOC]
+ write_serial_bytes(message, ser)
+
+ # Start next block hashing, wait and check status.
+ mode_cmd = chr(ord(SHA512_CTRL_NEXT_CMD) + (ord(mode) << SHA512_CTRL_MODE_LOW))
+ write_serial_bytes([SOC, WRITE_CMD, SHA512_ADDR_PREFIX, SHA512_ADDR_CTRL,
+ '\x00', '\x00', '\x00', mode_cmd, EOC], ser)
+ time.sleep(PROC_DELAY_TIME)
write_serial_bytes([SOC, READ_CMD, SHA512_ADDR_PREFIX, SHA512_ADDR_STATUS, EOC], ser)
- time.sleep(DELAY_TIME)
# Select the correct number of digest addresses to read.
if (mode == MODE_SHA_512_224):
@@ -446,7 +530,7 @@ def single_block_test_sha256(block, ser):
# Start initial block hashing, wait and check status.
write_serial_bytes([SOC, WRITE_CMD, SHA256_ADDR_PREFIX, SHA256_ADDR_CTRL,
'\x00', '\x00', '\x00', SHA256_CTRL_INIT_CMD, EOC], ser)
- time.sleep(DELAY_TIME)
+ time.sleep(PROC_DELAY_TIME)
write_serial_bytes([SOC, READ_CMD, SHA256_ADDR_PREFIX, SHA256_ADDR_STATUS, EOC], ser)
# Extract the digest.
@@ -471,7 +555,7 @@ def double_block_test_sha256(block1, block2, ser):
# Start initial block hashing, wait and check status.
write_serial_bytes([SOC, WRITE_CMD, SHA256_ADDR_PREFIX, SHA256_ADDR_CTRL,
'\x00', '\x00', '\x00', SHA256_CTRL_INIT_CMD, EOC], ser)
- time.sleep(DELAY_TIME)
+ time.sleep(PROC_DELAY_TIME)
write_serial_bytes([SOC, READ_CMD, SHA256_ADDR_PREFIX, SHA256_ADDR_STATUS, EOC], ser)
# Extract the first digest.
@@ -489,7 +573,7 @@ def double_block_test_sha256(block1, block2, ser):
# Start next block hashing, wait and check status.
write_serial_bytes([SOC, WRITE_CMD, SHA256_ADDR_PREFIX, SHA256_ADDR_CTRL,
'\x00', '\x00', '\x00', SHA256_CTRL_NEXT_CMD, EOC], ser)
- time.sleep(DELAY_TIME)
+ time.sleep(PROC_DELAY_TIME)
write_serial_bytes([SOC, READ_CMD, SHA256_ADDR_PREFIX, SHA256_ADDR_STATUS, EOC], ser)
# Extract the second digest.
@@ -514,7 +598,7 @@ def huge_message_test_sha256(block, n, ser):
# Start initial block hashing, wait.
write_serial_bytes([SOC, WRITE_CMD, SHA256_ADDR_PREFIX, SHA256_ADDR_CTRL,
'\x00', '\x00', '\x00', SHA256_CTRL_INIT_CMD, EOC], ser)
- time.sleep(DELAY_TIME)
+ time.sleep(PROC_DELAY_TIME)
print "Block 0 done."
# First block done.
@@ -531,14 +615,14 @@ def huge_message_test_sha256(block, n, ser):
write_serial_bytes([SOC, WRITE_CMD, SHA256_ADDR_PREFIX, SHA256_ADDR_CTRL,
'\x00', '\x00', '\x00', SHA256_CTRL_NEXT_CMD, EOC], ser)
print "Block %d done." % (i + 1)
- time.sleep(DELAY_TIME)
+ time.sleep(PROC_DELAY_TIME)
# Extract the digest for the current block.
for digest_addr in sha256_digest_addr:
message = [SOC, READ_CMD, SHA256_ADDR_PREFIX] + [digest_addr] + [EOC]
write_serial_bytes(message, ser)
print""
- time.sleep(DELAY_TIME)
+ time.sleep(PROC_DELAY_TIME)
#-------------------------------------------------------------------
@@ -557,7 +641,7 @@ def single_block_test_sha1(block, ser):
# Start initial block hashing, wait and check status.
write_serial_bytes([SOC, WRITE_CMD, SHA1_ADDR_PREFIX, SHA1_ADDR_CTRL,
'\x00', '\x00', '\x00', SHA1_CTRL_INIT_CMD, EOC], ser)
- time.sleep(DELAY_TIME)
+ time.sleep(PROC_DELAY_TIME)
write_serial_bytes([SOC, READ_CMD, SHA1_ADDR_PREFIX, SHA1_ADDR_STATUS, EOC], ser)
# Extract the digest.
@@ -582,7 +666,7 @@ def double_block_test_sha1(block1, block2, ser):
# Start initial block hashing, wait and check status.
write_serial_bytes([SOC, WRITE_CMD, SHA1_ADDR_PREFIX, SHA1_ADDR_CTRL,
'\x00', '\x00', '\x00', SHA1_CTRL_INIT_CMD, EOC], ser)
- time.sleep(DELAY_TIME)
+ time.sleep(PROC_DELAY_TIME)
write_serial_bytes([SOC, READ_CMD, SHA1_ADDR_PREFIX, SHA1_ADDR_STATUS, EOC], ser)
# Extract the first digest.
@@ -600,7 +684,7 @@ def double_block_test_sha1(block1, block2, ser):
# Start next block hashing, wait and check status.
write_serial_bytes([SOC, WRITE_CMD, SHA1_ADDR_PREFIX, SHA1_ADDR_CTRL,
'\x00', '\x00', '\x00', SHA1_CTRL_NEXT_CMD, EOC], ser)
- time.sleep(DELAY_TIME)
+ time.sleep(PROC_DELAY_TIME)
write_serial_bytes([SOC, READ_CMD, SHA1_ADDR_PREFIX, SHA1_ADDR_STATUS, EOC], ser)
# Extract the second digest.
@@ -753,7 +837,7 @@ def tc8(ser):
#-------------------------------------------------------------------
-# TC9: Single block test of SHA-512
+# TC9: Single block tests of SHA-512/x
#
# We do this for all modes.
#-------------------------------------------------------------------
@@ -801,6 +885,54 @@ def tc9(ser):
#-------------------------------------------------------------------
+# TC10: Dual block tests of SHA-512/x
+#
+# We do this for all modes.
+#-------------------------------------------------------------------
+def tc10(ser):
+ print "TC9: Single block message test for SHA-512/x."
+
+ tc10_224_expected = [0x23fec5bb, 0x94d60b23, 0x30819264, 0x0b0c4533,
+ 0x35d66473, 0x4fe40e72, 0x68674af9]
+
+ tc10_256_expected = [0x3928e184, 0xfb8690f8, 0x40da3988, 0x121d31be,
+ 0x65cb9d3e, 0xf83ee614, 0x6feac861, 0xe19b563a]
+
+ tc10_384_expected = [0xcb00753f, 0x45a35e8b, 0xb5a03d69, 0x9ac65007,
+ 0x272c32ab, 0x0eded163, 0x1a8b605a, 0x43ff5bed,
+ 0x8086072b, 0xa1e7cc23, 0x58baeca1, 0x34c825a7]
+
+ tc10_512_expected = [0x8e959b75, 0xdae313da, 0x8cf4f728, 0x14fc143f,
+ 0x8f7779c6, 0xeb9f7fa1, 0x7299aead, 0xb6889018,
+ 0x501d289e, 0x4900f7e4, 0x331b99de, 0xc4b5433a,
+ 0xc7d329ee, 0xb6dd2654, 0x5e96e55b, 0x874be909]
+
+ print "TC10-1: Expected digest values for SHA-512/224 as specified by NIST:"
+ for i in tc10_224_expected:
+ print("0x%08x " % i)
+ dual_block_test_sha512x(NIST_1024_DOUBLE0, NIST_1024_DOUBLE1, MODE_SHA_512_224, ser)
+ print("")
+
+ print "TC10-2: Expected digest values for SHA-512/256 as specified by NIST:"
+ for i in tc10_256_expected:
+ print("0x%08x " % i)
+ dual_block_test_sha512x(NIST_1024_DOUBLE0, NIST_1024_DOUBLE1, MODE_SHA_512_256, ser)
+ print("")
+
+ print "TC10-3: Expected digest values for SHA-384 as specified by NIST:"
+ for i in tc10_384_expected:
+ print("0x%08x " % i)
+ dual_block_test_sha512x(NIST_1024_DOUBLE0, NIST_1024_DOUBLE1, MODE_SHA_384, ser)
+ print("")
+
+ print "TC10-4: Expected digest values for SHA-512 as specified by NIST:"
+ for i in tc10_512_expected:
+ print("0x%08x " % i)
+ dual_block_test_sha512x(NIST_1024_DOUBLE0, NIST_1024_DOUBLE1, MODE_SHA_512, ser)
+ print("")
+
+
+#-------------------------------------------------------------------
# main()
#
# Parse any arguments and run the tests.
@@ -836,8 +968,8 @@ def main():
# Run the enabled test cases.
tc_list = [(tc1, False), (tc2, False), (tc3, False), (tc4, False),
- (tc5, False), (tc6, False), (tc7, False), (tc8, True),
- (tc9, True)]
+ (tc5, False), (tc6, False), (tc7, False), (tc8, False),
+ (tc9, False), (tc10, True)]
for (test_case, action) in tc_list:
if action:
test_case(ser)