summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLegrandin <helderijs@gmail.com>2013-05-16 23:09:27 +0200
committerDwayne Litzenberger <dlitz@dlitz.net>2013-10-20 13:30:21 -0700
commitaf392459f6a1962e676830ddf81e7b6d2667aa8b (patch)
tree9bf22471870cc83be083cfd333a472493b88ebc1
parent77b0b9123c32b181f7f7a0072b2baa6312620f66 (diff)
downloadpycrypto-af392459f6a1962e676830ddf81e7b6d2667aa8b.tar.gz
MAC unit tests become independent of hashes
The MAC unit tests assume that the MAC algorithm is based on hash functions (HMAC). Additionally, a single test vector is quite complex in that it includes result for multiple tests (each performed on the same data, but with different hashes). This patch simplifies the MAC unit test so that it does not depend on hashes and a test vector is simply made up by: * 1 input * 1 result * All parameters to pass to the new() function [dlitz@dlitz.net: Replaced custom MacMismatchError with ValueError.] [dlitz@dlitz.net: Replaced 'import *' with appropriate imports.] [dlitz@dlitz.net: Whitespace fixed with "git rebase --whitespace=fix"]
-rw-r--r--lib/Crypto/SelfTest/Hash/common.py98
-rw-r--r--lib/Crypto/SelfTest/Hash/test_HMAC.py36
2 files changed, 71 insertions, 63 deletions
diff --git a/lib/Crypto/SelfTest/Hash/common.py b/lib/Crypto/SelfTest/Hash/common.py
index 4976690..968caa2 100644
--- a/lib/Crypto/SelfTest/Hash/common.py
+++ b/lib/Crypto/SelfTest/Hash/common.py
@@ -162,62 +162,60 @@ class GenericHashConstructorTest(unittest.TestCase):
class MACSelfTest(unittest.TestCase):
- def __init__(self, hashmod, description, expected_dict, input, key, hashmods):
+ def __init__(self, module, description, result, input, key, params):
unittest.TestCase.__init__(self)
- self.hashmod = hashmod
- self.expected_dict = expected_dict
+ self.module = module
+ self.result = result
self.input = input
self.key = key
- self.hashmods = hashmods
+ self.params = params
self.description = description
def shortDescription(self):
return self.description
def runTest(self):
- for hashname in self.expected_dict.keys():
- hashmod = self.hashmods[hashname]
- key = binascii.a2b_hex(b(self.key))
- data = binascii.a2b_hex(b(self.input))
-
- # Strip whitespace from the expected string (which should be in lowercase-hex)
- expected = b("".join(self.expected_dict[hashname].split()))
-
- h = self.hashmod.new(key, digestmod=hashmod)
- h.update(data)
- out1_bin = h.digest()
- out1 = binascii.b2a_hex(out1_bin)
- out2 = h.hexdigest()
-
- # Verify that correct MAC does not raise any exception
- h.hexverify(out1)
- h.verify(out1_bin)
-
- # Verify that incorrect MAC does raise ValueError exception
- wrong_mac = strxor_c(out1_bin, 255)
- self.assertRaises(ValueError, h.verify, wrong_mac)
- self.assertRaises(ValueError, h.hexverify, "4556")
-
- h = self.hashmod.new(key, data, hashmod)
-
- out3 = h.hexdigest()
- out4 = binascii.b2a_hex(h.digest())
-
- # Test .copy()
- h2 = h.copy()
- h.update(b("blah blah blah")) # Corrupt the original hash object
- out5 = binascii.b2a_hex(h2.digest()) # The copied hash object should return the correct result
-
- # PY3K: hexdigest() should return str(), and digest() bytes
- self.assertEqual(expected, out1)
- if sys.version_info[0] == 2:
- self.assertEqual(expected, out2)
- self.assertEqual(expected, out3)
- else:
- self.assertEqual(expected.decode(), out2)
- self.assertEqual(expected.decode(), out3)
- self.assertEqual(expected, out4)
- self.assertEqual(expected, out5)
+ key = binascii.a2b_hex(b(self.key))
+ data = binascii.a2b_hex(b(self.input))
+
+ # Strip whitespace from the expected string (which should be in lowercase-hex)
+ expected = b("".join(self.result.split()))
+
+ h = self.module.new(key, **self.params)
+ h.update(data)
+ out1_bin = h.digest()
+ out1 = binascii.b2a_hex(h.digest())
+ out2 = h.hexdigest()
+
+ # Verify that correct MAC does not raise any exception
+ h.hexverify(out1)
+ h.verify(out1_bin)
+
+ # Verify that incorrect MAC does raise ValueError exception
+ wrong_mac = strxor_c(out1_bin, 255)
+ self.assertRaises(ValueError, h.verify, wrong_mac)
+ self.assertRaises(ValueError, h.hexverify, "4556")
+
+ h = self.module.new(key, data, **self.params)
+
+ out3 = h.hexdigest()
+ out4 = binascii.b2a_hex(h.digest())
+
+ # Test .copy()
+ h2 = h.copy()
+ h.update(b("blah blah blah")) # Corrupt the original hash object
+ out5 = binascii.b2a_hex(h2.digest()) # The copied hash object should return the correct result
+
+ # PY3K: hexdigest() should return str(), and digest() bytes
+ self.assertEqual(expected, out1)
+ if sys.version_info[0] == 2:
+ self.assertEqual(expected, out2)
+ self.assertEqual(expected, out3)
+ else:
+ self.assertEqual(expected.decode(), out2)
+ self.assertEqual(expected.decode(), out3)
+ self.assertEqual(expected, out4)
+ self.assertEqual(expected, out5)
def make_hash_tests(module, module_name, test_data, digest_size, oid=None):
tests = []
@@ -239,13 +237,13 @@ def make_hash_tests(module, module_name, test_data, digest_size, oid=None):
tests.append(GenericHashConstructorTest(module))
return tests
-def make_mac_tests(module, module_name, test_data, hashmods):
+def make_mac_tests(module, module_name, test_data):
tests = []
for i in range(len(test_data)):
row = test_data[i]
- (key, data, results, description) = row
+ (key, data, results, description, params) = row
name = "%s #%d: %s" % (module_name, i+1, description)
- tests.append(MACSelfTest(module, name, results, data, key, hashmods))
+ tests.append(MACSelfTest(module, name, results, data, key, params))
return tests
# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Hash/test_HMAC.py b/lib/Crypto/SelfTest/Hash/test_HMAC.py
index 85bdf47..baaea5e 100644
--- a/lib/Crypto/SelfTest/Hash/test_HMAC.py
+++ b/lib/Crypto/SelfTest/Hash/test_HMAC.py
@@ -29,13 +29,17 @@ __revision__ = "$Id$"
from common import dict # For compatibility with Python 2.1 and 2.2
from Crypto.Util.py3compat import *
+from Crypto.Hash import MD5, SHA1, SHA224, SHA256, SHA384, SHA512, HMAC
+
+default_hash = None
+
# This is a list of (key, data, results, description) tuples.
test_data = [
## Test vectors from RFC 2202 ##
# Test that the default hashmod is MD5
('0b' * 16,
'4869205468657265',
- dict(default='9294727a3638bb1c13f48ef8158bfc9d'),
+ dict(default_hash='9294727a3638bb1c13f48ef8158bfc9d'),
'default-is-MD5'),
# Test case 1 (MD5)
@@ -175,9 +179,7 @@ test_data = [
bfdc63644f0713938a7f51535c3a35e2
'''),
'RFC 4231 #7 (HMAC-SHA256)'),
-]
-hashlib_test_data = [
# Test case 8 (SHA224)
('4a656665',
'7768617420646f2079612077616e74'
@@ -203,17 +205,25 @@ hashlib_test_data = [
def get_tests(config={}):
global test_data
- from Crypto.Hash import HMAC, MD5, SHA1, SHA256
from common import make_mac_tests
- hashmods = dict(MD5=MD5, SHA1=SHA1, SHA256=SHA256, default=None)
- try:
- from Crypto.Hash import SHA224, SHA384, SHA512
- hashmods.update(dict(SHA224=SHA224, SHA384=SHA384, SHA512=SHA512))
- test_data += hashlib_test_data
- except ImportError:
- import sys
- sys.stderr.write("SelfTest: warning: not testing HMAC-SHA224/384/512 (not available)\n")
- return make_mac_tests(HMAC, "HMAC", test_data, hashmods)
+
+ # A test vector contains multiple results, each one for a
+ # different hash algorithm.
+ # Here we expand each test vector into multiple ones,
+ # and add the relevant parameters that will be passed to new()
+ exp_test_data = []
+ for row in test_data:
+ for modname in row[2].keys():
+ t = list(row)
+ t[2] = row[2][modname]
+ try:
+ t.append(dict(digestmod=globals()[modname]))
+ exp_test_data.append(t)
+ except AttributeError:
+ import sys
+ sys.stderr.write("SelfTest: warning: not testing HMAC-%s (not available)\n" % modname)
+
+ return make_mac_tests(HMAC, "HMAC", exp_test_data)
if __name__ == '__main__':
import unittest