xref: /freebsd/tests/sys/opencrypto/cryptotest.py (revision de0f7dca5eb3558d5b9d5cf25e379f614b61af17)
1369ee090SLi-Wen Hsu#!/usr/local/bin/python2
208fca7a5SJohn-Mark Gurney#
308fca7a5SJohn-Mark Gurney# Copyright (c) 2014 The FreeBSD Foundation
408fca7a5SJohn-Mark Gurney# All rights reserved.
508fca7a5SJohn-Mark Gurney#
608fca7a5SJohn-Mark Gurney# This software was developed by John-Mark Gurney under
708fca7a5SJohn-Mark Gurney# the sponsorship from the FreeBSD Foundation.
808fca7a5SJohn-Mark Gurney# Redistribution and use in source and binary forms, with or without
908fca7a5SJohn-Mark Gurney# modification, are permitted provided that the following conditions
1008fca7a5SJohn-Mark Gurney# are met:
1108fca7a5SJohn-Mark Gurney# 1.  Redistributions of source code must retain the above copyright
1208fca7a5SJohn-Mark Gurney#     notice, this list of conditions and the following disclaimer.
1308fca7a5SJohn-Mark Gurney# 2.  Redistributions in binary form must reproduce the above copyright
1408fca7a5SJohn-Mark Gurney#     notice, this list of conditions and the following disclaimer in the
1508fca7a5SJohn-Mark Gurney#     documentation and/or other materials provided with the distribution.
1608fca7a5SJohn-Mark Gurney#
1708fca7a5SJohn-Mark Gurney# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1808fca7a5SJohn-Mark Gurney# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1908fca7a5SJohn-Mark Gurney# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2008fca7a5SJohn-Mark Gurney# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2108fca7a5SJohn-Mark Gurney# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2208fca7a5SJohn-Mark Gurney# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2308fca7a5SJohn-Mark Gurney# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2408fca7a5SJohn-Mark Gurney# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2508fca7a5SJohn-Mark Gurney# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2608fca7a5SJohn-Mark Gurney# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2708fca7a5SJohn-Mark Gurney# SUCH DAMAGE.
2808fca7a5SJohn-Mark Gurney#
2908fca7a5SJohn-Mark Gurney# $FreeBSD$
3008fca7a5SJohn-Mark Gurney#
3108fca7a5SJohn-Mark Gurney
32d86680b0SEnji Cooperfrom __future__ import print_function
33a317fb03SConrad Meyerimport errno
3408fca7a5SJohn-Mark Gurneyimport cryptodev
3508fca7a5SJohn-Mark Gurneyimport itertools
3608fca7a5SJohn-Mark Gurneyimport os
3708fca7a5SJohn-Mark Gurneyimport struct
3808fca7a5SJohn-Mark Gurneyimport unittest
3908fca7a5SJohn-Mark Gurneyfrom cryptodev import *
4008fca7a5SJohn-Mark Gurneyfrom glob import iglob
4108fca7a5SJohn-Mark Gurney
4208fca7a5SJohn-Mark Gurneykatdir = '/usr/local/share/nist-kat'
4308fca7a5SJohn-Mark Gurney
4408fca7a5SJohn-Mark Gurneydef katg(base, glob):
45aeb5c8e6SJohn Baldwin	assert os.path.exists(katdir), "Please 'pkg install nist-kat'"
46aeb5c8e6SJohn Baldwin	if not os.path.exists(os.path.join(katdir, base)):
47aeb5c8e6SJohn Baldwin		raise unittest.SkipTest("Missing %s test vectors" % (base))
4808fca7a5SJohn-Mark Gurney	return iglob(os.path.join(katdir, base, glob))
4908fca7a5SJohn-Mark Gurney
50844d9543SConrad Meyeraesmodules = [ 'cryptosoft0', 'aesni0', 'ccr0', 'ccp0' ]
5108fca7a5SJohn-Mark Gurneydesmodules = [ 'cryptosoft0', ]
52844d9543SConrad Meyershamodules = [ 'cryptosoft0', 'aesni0', 'ccr0', 'ccp0' ]
5308fca7a5SJohn-Mark Gurney
5408fca7a5SJohn-Mark Gurneydef GenTestCase(cname):
5508fca7a5SJohn-Mark Gurney	try:
5608fca7a5SJohn-Mark Gurney		crid = cryptodev.Crypto.findcrid(cname)
5708fca7a5SJohn-Mark Gurney	except IOError:
5808fca7a5SJohn-Mark Gurney		return None
5908fca7a5SJohn-Mark Gurney
6008fca7a5SJohn-Mark Gurney	class GendCryptoTestCase(unittest.TestCase):
6108fca7a5SJohn-Mark Gurney		###############
6208fca7a5SJohn-Mark Gurney		##### AES #####
6308fca7a5SJohn-Mark Gurney		###############
64c091d0d9SJohn Baldwin		@unittest.skipIf(cname not in aesmodules, 'skipping AES-XTS on %s' % (cname))
6508fca7a5SJohn-Mark Gurney		def test_xts(self):
6608fca7a5SJohn-Mark Gurney			for i in katg('XTSTestVectors/format tweak value input - data unit seq no', '*.rsp'):
6708fca7a5SJohn-Mark Gurney				self.runXTS(i, cryptodev.CRYPTO_AES_XTS)
6808fca7a5SJohn-Mark Gurney
69c091d0d9SJohn Baldwin		@unittest.skipIf(cname not in aesmodules, 'skipping AES-CBC on %s' % (cname))
7008fca7a5SJohn-Mark Gurney		def test_cbc(self):
7108fca7a5SJohn-Mark Gurney			for i in katg('KAT_AES', 'CBC[GKV]*.rsp'):
7208fca7a5SJohn-Mark Gurney				self.runCBC(i)
7308fca7a5SJohn-Mark Gurney
74c091d0d9SJohn Baldwin		@unittest.skipIf(cname not in aesmodules, 'skipping AES-GCM on %s' % (cname))
7508fca7a5SJohn-Mark Gurney		def test_gcm(self):
7608fca7a5SJohn-Mark Gurney			for i in katg('gcmtestvectors', 'gcmEncrypt*'):
7708fca7a5SJohn-Mark Gurney				self.runGCM(i, 'ENCRYPT')
7808fca7a5SJohn-Mark Gurney
7908fca7a5SJohn-Mark Gurney			for i in katg('gcmtestvectors', 'gcmDecrypt*'):
8008fca7a5SJohn-Mark Gurney				self.runGCM(i, 'DECRYPT')
8108fca7a5SJohn-Mark Gurney
8208fca7a5SJohn-Mark Gurney		_gmacsizes = { 32: cryptodev.CRYPTO_AES_256_NIST_GMAC,
8308fca7a5SJohn-Mark Gurney			24: cryptodev.CRYPTO_AES_192_NIST_GMAC,
8408fca7a5SJohn-Mark Gurney			16: cryptodev.CRYPTO_AES_128_NIST_GMAC,
8508fca7a5SJohn-Mark Gurney		}
8608fca7a5SJohn-Mark Gurney		def runGCM(self, fname, mode):
8708fca7a5SJohn-Mark Gurney			curfun = None
8808fca7a5SJohn-Mark Gurney			if mode == 'ENCRYPT':
8908fca7a5SJohn-Mark Gurney				swapptct = False
9008fca7a5SJohn-Mark Gurney				curfun = Crypto.encrypt
9108fca7a5SJohn-Mark Gurney			elif mode == 'DECRYPT':
9208fca7a5SJohn-Mark Gurney				swapptct = True
9308fca7a5SJohn-Mark Gurney				curfun = Crypto.decrypt
9408fca7a5SJohn-Mark Gurney			else:
95d86680b0SEnji Cooper				raise RuntimeError('unknown mode: %r' % repr(mode))
9608fca7a5SJohn-Mark Gurney
9708fca7a5SJohn-Mark Gurney			for bogusmode, lines in cryptodev.KATParser(fname,
9808fca7a5SJohn-Mark Gurney			    [ 'Count', 'Key', 'IV', 'CT', 'AAD', 'Tag', 'PT', ]):
9908fca7a5SJohn-Mark Gurney				for data in lines:
10008fca7a5SJohn-Mark Gurney					curcnt = int(data['Count'])
10108fca7a5SJohn-Mark Gurney					cipherkey = data['Key'].decode('hex')
10208fca7a5SJohn-Mark Gurney					iv = data['IV'].decode('hex')
10308fca7a5SJohn-Mark Gurney					aad = data['AAD'].decode('hex')
10408fca7a5SJohn-Mark Gurney					tag = data['Tag'].decode('hex')
10508fca7a5SJohn-Mark Gurney					if 'FAIL' not in data:
10608fca7a5SJohn-Mark Gurney						pt = data['PT'].decode('hex')
10708fca7a5SJohn-Mark Gurney					ct = data['CT'].decode('hex')
10808fca7a5SJohn-Mark Gurney
10908fca7a5SJohn-Mark Gurney					if len(iv) != 12:
11008fca7a5SJohn-Mark Gurney						# XXX - isn't supported
11108fca7a5SJohn-Mark Gurney						continue
11208fca7a5SJohn-Mark Gurney
113844d9543SConrad Meyer					try:
11408fca7a5SJohn-Mark Gurney						c = Crypto(cryptodev.CRYPTO_AES_NIST_GCM_16,
11508fca7a5SJohn-Mark Gurney						    cipherkey,
11608fca7a5SJohn-Mark Gurney						    mac=self._gmacsizes[len(cipherkey)],
117*de0f7dcaSJohn Baldwin						    mackey=cipherkey, crid=crid,
118*de0f7dcaSJohn Baldwin						    maclen=16)
119844d9543SConrad Meyer					except EnvironmentError, e:
120844d9543SConrad Meyer						# Can't test algorithms the driver does not support.
121844d9543SConrad Meyer						if e.errno != errno.EOPNOTSUPP:
122844d9543SConrad Meyer							raise
123844d9543SConrad Meyer						continue
12408fca7a5SJohn-Mark Gurney
12508fca7a5SJohn-Mark Gurney					if mode == 'ENCRYPT':
126844d9543SConrad Meyer						try:
12708fca7a5SJohn-Mark Gurney							rct, rtag = c.encrypt(pt, iv, aad)
128844d9543SConrad Meyer						except EnvironmentError, e:
129844d9543SConrad Meyer							# Can't test inputs the driver does not support.
130844d9543SConrad Meyer							if e.errno != errno.EINVAL:
131844d9543SConrad Meyer								raise
132844d9543SConrad Meyer							continue
13308fca7a5SJohn-Mark Gurney						rtag = rtag[:len(tag)]
13408fca7a5SJohn-Mark Gurney						data['rct'] = rct.encode('hex')
13508fca7a5SJohn-Mark Gurney						data['rtag'] = rtag.encode('hex')
136d86680b0SEnji Cooper						self.assertEqual(rct, ct, repr(data))
137d86680b0SEnji Cooper						self.assertEqual(rtag, tag, repr(data))
13808fca7a5SJohn-Mark Gurney					else:
13908fca7a5SJohn-Mark Gurney						if len(tag) != 16:
14008fca7a5SJohn-Mark Gurney							continue
14108fca7a5SJohn-Mark Gurney						args = (ct, iv, aad, tag)
14208fca7a5SJohn-Mark Gurney						if 'FAIL' in data:
14308fca7a5SJohn-Mark Gurney							self.assertRaises(IOError,
14408fca7a5SJohn-Mark Gurney								c.decrypt, *args)
14508fca7a5SJohn-Mark Gurney						else:
146844d9543SConrad Meyer							try:
14708fca7a5SJohn-Mark Gurney								rpt, rtag = c.decrypt(*args)
148844d9543SConrad Meyer							except EnvironmentError, e:
149844d9543SConrad Meyer								# Can't test inputs the driver does not support.
150844d9543SConrad Meyer								if e.errno != errno.EINVAL:
151844d9543SConrad Meyer									raise
152844d9543SConrad Meyer								continue
15308fca7a5SJohn-Mark Gurney							data['rpt'] = rpt.encode('hex')
15408fca7a5SJohn-Mark Gurney							data['rtag'] = rtag.encode('hex')
15508fca7a5SJohn-Mark Gurney							self.assertEqual(rpt, pt,
156d86680b0SEnji Cooper							    repr(data))
15708fca7a5SJohn-Mark Gurney
15808fca7a5SJohn-Mark Gurney		def runCBC(self, fname):
15908fca7a5SJohn-Mark Gurney			curfun = None
16008fca7a5SJohn-Mark Gurney			for mode, lines in cryptodev.KATParser(fname,
16108fca7a5SJohn-Mark Gurney			    [ 'COUNT', 'KEY', 'IV', 'PLAINTEXT', 'CIPHERTEXT', ]):
16208fca7a5SJohn-Mark Gurney				if mode == 'ENCRYPT':
16308fca7a5SJohn-Mark Gurney					swapptct = False
16408fca7a5SJohn-Mark Gurney					curfun = Crypto.encrypt
16508fca7a5SJohn-Mark Gurney				elif mode == 'DECRYPT':
16608fca7a5SJohn-Mark Gurney					swapptct = True
16708fca7a5SJohn-Mark Gurney					curfun = Crypto.decrypt
16808fca7a5SJohn-Mark Gurney				else:
169d86680b0SEnji Cooper					raise RuntimeError('unknown mode: %r' % repr(mode))
17008fca7a5SJohn-Mark Gurney
17108fca7a5SJohn-Mark Gurney				for data in lines:
17208fca7a5SJohn-Mark Gurney					curcnt = int(data['COUNT'])
17308fca7a5SJohn-Mark Gurney					cipherkey = data['KEY'].decode('hex')
17408fca7a5SJohn-Mark Gurney					iv = data['IV'].decode('hex')
17508fca7a5SJohn-Mark Gurney					pt = data['PLAINTEXT'].decode('hex')
17608fca7a5SJohn-Mark Gurney					ct = data['CIPHERTEXT'].decode('hex')
17708fca7a5SJohn-Mark Gurney
17808fca7a5SJohn-Mark Gurney					if swapptct:
17908fca7a5SJohn-Mark Gurney						pt, ct = ct, pt
18008fca7a5SJohn-Mark Gurney					# run the fun
18108fca7a5SJohn-Mark Gurney					c = Crypto(cryptodev.CRYPTO_AES_CBC, cipherkey, crid=crid)
18208fca7a5SJohn-Mark Gurney					r = curfun(c, pt, iv)
18308fca7a5SJohn-Mark Gurney					self.assertEqual(r, ct)
18408fca7a5SJohn-Mark Gurney
18508fca7a5SJohn-Mark Gurney		def runXTS(self, fname, meth):
18608fca7a5SJohn-Mark Gurney			curfun = None
18708fca7a5SJohn-Mark Gurney			for mode, lines in cryptodev.KATParser(fname,
18808fca7a5SJohn-Mark Gurney			    [ 'COUNT', 'DataUnitLen', 'Key', 'DataUnitSeqNumber', 'PT',
18908fca7a5SJohn-Mark Gurney			    'CT' ]):
19008fca7a5SJohn-Mark Gurney				if mode == 'ENCRYPT':
19108fca7a5SJohn-Mark Gurney					swapptct = False
19208fca7a5SJohn-Mark Gurney					curfun = Crypto.encrypt
19308fca7a5SJohn-Mark Gurney				elif mode == 'DECRYPT':
19408fca7a5SJohn-Mark Gurney					swapptct = True
19508fca7a5SJohn-Mark Gurney					curfun = Crypto.decrypt
19608fca7a5SJohn-Mark Gurney				else:
197d86680b0SEnji Cooper					raise RuntimeError('unknown mode: %r' % repr(mode))
19808fca7a5SJohn-Mark Gurney
19908fca7a5SJohn-Mark Gurney				for data in lines:
20008fca7a5SJohn-Mark Gurney					curcnt = int(data['COUNT'])
20108fca7a5SJohn-Mark Gurney					nbits = int(data['DataUnitLen'])
20208fca7a5SJohn-Mark Gurney					cipherkey = data['Key'].decode('hex')
20308fca7a5SJohn-Mark Gurney					iv = struct.pack('QQ', int(data['DataUnitSeqNumber']), 0)
20408fca7a5SJohn-Mark Gurney					pt = data['PT'].decode('hex')
20508fca7a5SJohn-Mark Gurney					ct = data['CT'].decode('hex')
20608fca7a5SJohn-Mark Gurney
20708fca7a5SJohn-Mark Gurney					if nbits % 128 != 0:
20808fca7a5SJohn-Mark Gurney						# XXX - mark as skipped
20908fca7a5SJohn-Mark Gurney						continue
21008fca7a5SJohn-Mark Gurney					if swapptct:
21108fca7a5SJohn-Mark Gurney						pt, ct = ct, pt
21208fca7a5SJohn-Mark Gurney					# run the fun
213844d9543SConrad Meyer					try:
21408fca7a5SJohn-Mark Gurney						c = Crypto(meth, cipherkey, crid=crid)
21508fca7a5SJohn-Mark Gurney						r = curfun(c, pt, iv)
216844d9543SConrad Meyer					except EnvironmentError, e:
217844d9543SConrad Meyer						# Can't test hashes the driver does not support.
218844d9543SConrad Meyer						if e.errno != errno.EOPNOTSUPP:
219844d9543SConrad Meyer							raise
220844d9543SConrad Meyer						continue
22108fca7a5SJohn-Mark Gurney					self.assertEqual(r, ct)
22208fca7a5SJohn-Mark Gurney
22308fca7a5SJohn-Mark Gurney		###############
22408fca7a5SJohn-Mark Gurney		##### DES #####
22508fca7a5SJohn-Mark Gurney		###############
226d86680b0SEnji Cooper		@unittest.skipIf(cname not in desmodules, 'skipping DES on %s' % (cname))
22708fca7a5SJohn-Mark Gurney		def test_tdes(self):
22808fca7a5SJohn-Mark Gurney			for i in katg('KAT_TDES', 'TCBC[a-z]*.rsp'):
22908fca7a5SJohn-Mark Gurney				self.runTDES(i)
23008fca7a5SJohn-Mark Gurney
23108fca7a5SJohn-Mark Gurney		def runTDES(self, fname):
23208fca7a5SJohn-Mark Gurney			curfun = None
23308fca7a5SJohn-Mark Gurney			for mode, lines in cryptodev.KATParser(fname,
23408fca7a5SJohn-Mark Gurney			    [ 'COUNT', 'KEYs', 'IV', 'PLAINTEXT', 'CIPHERTEXT', ]):
23508fca7a5SJohn-Mark Gurney				if mode == 'ENCRYPT':
23608fca7a5SJohn-Mark Gurney					swapptct = False
23708fca7a5SJohn-Mark Gurney					curfun = Crypto.encrypt
23808fca7a5SJohn-Mark Gurney				elif mode == 'DECRYPT':
23908fca7a5SJohn-Mark Gurney					swapptct = True
24008fca7a5SJohn-Mark Gurney					curfun = Crypto.decrypt
24108fca7a5SJohn-Mark Gurney				else:
242d86680b0SEnji Cooper					raise RuntimeError('unknown mode: %r' % repr(mode))
24308fca7a5SJohn-Mark Gurney
24408fca7a5SJohn-Mark Gurney				for data in lines:
24508fca7a5SJohn-Mark Gurney					curcnt = int(data['COUNT'])
24608fca7a5SJohn-Mark Gurney					key = data['KEYs'] * 3
24708fca7a5SJohn-Mark Gurney					cipherkey = key.decode('hex')
24808fca7a5SJohn-Mark Gurney					iv = data['IV'].decode('hex')
24908fca7a5SJohn-Mark Gurney					pt = data['PLAINTEXT'].decode('hex')
25008fca7a5SJohn-Mark Gurney					ct = data['CIPHERTEXT'].decode('hex')
25108fca7a5SJohn-Mark Gurney
25208fca7a5SJohn-Mark Gurney					if swapptct:
25308fca7a5SJohn-Mark Gurney						pt, ct = ct, pt
25408fca7a5SJohn-Mark Gurney					# run the fun
25508fca7a5SJohn-Mark Gurney					c = Crypto(cryptodev.CRYPTO_3DES_CBC, cipherkey, crid=crid)
25608fca7a5SJohn-Mark Gurney					r = curfun(c, pt, iv)
25708fca7a5SJohn-Mark Gurney					self.assertEqual(r, ct)
25808fca7a5SJohn-Mark Gurney
25908fca7a5SJohn-Mark Gurney		###############
26008fca7a5SJohn-Mark Gurney		##### SHA #####
26108fca7a5SJohn-Mark Gurney		###############
262d86680b0SEnji Cooper		@unittest.skipIf(cname not in shamodules, 'skipping SHA on %s' % str(cname))
26308fca7a5SJohn-Mark Gurney		def test_sha(self):
264*de0f7dcaSJohn Baldwin			for i in katg('shabytetestvectors', 'SHA*Msg.rsp'):
265*de0f7dcaSJohn Baldwin				self.runSHA(i)
266*de0f7dcaSJohn Baldwin
267*de0f7dcaSJohn Baldwin		def runSHA(self, fname):
268*de0f7dcaSJohn Baldwin			# Skip SHA512_(224|256) tests
269*de0f7dcaSJohn Baldwin			if fname.find('SHA512_') != -1:
270*de0f7dcaSJohn Baldwin				return
271*de0f7dcaSJohn Baldwin
272*de0f7dcaSJohn Baldwin			for hashlength, lines in cryptodev.KATParser(fname,
273*de0f7dcaSJohn Baldwin			    [ 'Len', 'Msg', 'MD' ]):
274*de0f7dcaSJohn Baldwin				# E.g., hashlength will be "L=20" (bytes)
275*de0f7dcaSJohn Baldwin				hashlen = int(hashlength.split("=")[1])
276*de0f7dcaSJohn Baldwin
277*de0f7dcaSJohn Baldwin				if hashlen == 20:
278*de0f7dcaSJohn Baldwin					alg = cryptodev.CRYPTO_SHA1
279*de0f7dcaSJohn Baldwin				elif hashlen == 28:
280*de0f7dcaSJohn Baldwin					alg = cryptodev.CRYPTO_SHA2_224
281*de0f7dcaSJohn Baldwin				elif hashlen == 32:
282*de0f7dcaSJohn Baldwin					alg = cryptodev.CRYPTO_SHA2_256
283*de0f7dcaSJohn Baldwin				elif hashlen == 48:
284*de0f7dcaSJohn Baldwin					alg = cryptodev.CRYPTO_SHA2_384
285*de0f7dcaSJohn Baldwin				elif hashlen == 64:
286*de0f7dcaSJohn Baldwin					alg = cryptodev.CRYPTO_SHA2_512
287*de0f7dcaSJohn Baldwin				else:
288*de0f7dcaSJohn Baldwin					# Skip unsupported hashes
289*de0f7dcaSJohn Baldwin					# Slurp remaining input in section
290*de0f7dcaSJohn Baldwin					for data in lines:
291*de0f7dcaSJohn Baldwin						continue
292*de0f7dcaSJohn Baldwin					continue
293*de0f7dcaSJohn Baldwin
294*de0f7dcaSJohn Baldwin				for data in lines:
295*de0f7dcaSJohn Baldwin					msg = data['Msg'].decode('hex')
296*de0f7dcaSJohn Baldwin                                        msg = msg[:int(data['Len'])]
297*de0f7dcaSJohn Baldwin					md = data['MD'].decode('hex')
298*de0f7dcaSJohn Baldwin
299*de0f7dcaSJohn Baldwin					try:
300*de0f7dcaSJohn Baldwin						c = Crypto(mac=alg, crid=crid,
301*de0f7dcaSJohn Baldwin						    maclen=hashlen)
302*de0f7dcaSJohn Baldwin					except EnvironmentError, e:
303*de0f7dcaSJohn Baldwin						# Can't test hashes the driver does not support.
304*de0f7dcaSJohn Baldwin						if e.errno != errno.EOPNOTSUPP:
305*de0f7dcaSJohn Baldwin							raise
306*de0f7dcaSJohn Baldwin						continue
307*de0f7dcaSJohn Baldwin
308*de0f7dcaSJohn Baldwin					_, r = c.encrypt(msg, iv="")
309*de0f7dcaSJohn Baldwin
310*de0f7dcaSJohn Baldwin					self.assertEqual(r, md, "Actual: " + \
311*de0f7dcaSJohn Baldwin					    repr(r.encode("hex")) + " Expected: " + repr(data) + " on " + cname)
31208fca7a5SJohn-Mark Gurney
313c091d0d9SJohn Baldwin		@unittest.skipIf(cname not in shamodules, 'skipping SHA-HMAC on %s' % str(cname))
31408fca7a5SJohn-Mark Gurney		def test_sha1hmac(self):
31508fca7a5SJohn-Mark Gurney			for i in katg('hmactestvectors', 'HMAC.rsp'):
31608fca7a5SJohn-Mark Gurney				self.runSHA1HMAC(i)
31708fca7a5SJohn-Mark Gurney
31808fca7a5SJohn-Mark Gurney		def runSHA1HMAC(self, fname):
319005fdbbcSConrad Meyer			for hashlength, lines in cryptodev.KATParser(fname,
32008fca7a5SJohn-Mark Gurney			    [ 'Count', 'Klen', 'Tlen', 'Key', 'Msg', 'Mac' ]):
321005fdbbcSConrad Meyer				# E.g., hashlength will be "L=20" (bytes)
322005fdbbcSConrad Meyer				hashlen = int(hashlength.split("=")[1])
323005fdbbcSConrad Meyer
324005fdbbcSConrad Meyer				blocksize = None
325005fdbbcSConrad Meyer				if hashlen == 20:
326005fdbbcSConrad Meyer					alg = cryptodev.CRYPTO_SHA1_HMAC
327005fdbbcSConrad Meyer					blocksize = 64
328005fdbbcSConrad Meyer				elif hashlen == 28:
329c87ada6aSJohn Baldwin					alg = cryptodev.CRYPTO_SHA2_224_HMAC
330c87ada6aSJohn Baldwin					blocksize = 64
331005fdbbcSConrad Meyer				elif hashlen == 32:
332005fdbbcSConrad Meyer					alg = cryptodev.CRYPTO_SHA2_256_HMAC
333005fdbbcSConrad Meyer					blocksize = 64
334005fdbbcSConrad Meyer				elif hashlen == 48:
335005fdbbcSConrad Meyer					alg = cryptodev.CRYPTO_SHA2_384_HMAC
336005fdbbcSConrad Meyer					blocksize = 128
337005fdbbcSConrad Meyer				elif hashlen == 64:
338005fdbbcSConrad Meyer					alg = cryptodev.CRYPTO_SHA2_512_HMAC
339005fdbbcSConrad Meyer					blocksize = 128
340005fdbbcSConrad Meyer				else:
341005fdbbcSConrad Meyer					# Skip unsupported hashes
342005fdbbcSConrad Meyer					# Slurp remaining input in section
343005fdbbcSConrad Meyer					for data in lines:
344005fdbbcSConrad Meyer						continue
345005fdbbcSConrad Meyer					continue
346005fdbbcSConrad Meyer
34708fca7a5SJohn-Mark Gurney				for data in lines:
34808fca7a5SJohn-Mark Gurney					key = data['Key'].decode('hex')
34908fca7a5SJohn-Mark Gurney					msg = data['Msg'].decode('hex')
35008fca7a5SJohn-Mark Gurney					mac = data['Mac'].decode('hex')
351005fdbbcSConrad Meyer					tlen = int(data['Tlen'])
35208fca7a5SJohn-Mark Gurney
353005fdbbcSConrad Meyer					if len(key) > blocksize:
35408fca7a5SJohn-Mark Gurney						continue
35508fca7a5SJohn-Mark Gurney
356a317fb03SConrad Meyer					try:
357005fdbbcSConrad Meyer						c = Crypto(mac=alg, mackey=key,
358*de0f7dcaSJohn Baldwin						    crid=crid, maclen=hashlen)
359a317fb03SConrad Meyer					except EnvironmentError, e:
360a317fb03SConrad Meyer						# Can't test hashes the driver does not support.
361a317fb03SConrad Meyer						if e.errno != errno.EOPNOTSUPP:
362a317fb03SConrad Meyer							raise
363a317fb03SConrad Meyer						continue
36408fca7a5SJohn-Mark Gurney
365005fdbbcSConrad Meyer					_, r = c.encrypt(msg, iv="")
366005fdbbcSConrad Meyer
367*de0f7dcaSJohn Baldwin					self.assertEqual(r[:tlen], mac, "Actual: " + \
368*de0f7dcaSJohn Baldwin					    repr(r.encode("hex")) + " Expected: " + repr(data))
36908fca7a5SJohn-Mark Gurney
37008fca7a5SJohn-Mark Gurney	return GendCryptoTestCase
37108fca7a5SJohn-Mark Gurney
37208fca7a5SJohn-Mark Gurneycryptosoft = GenTestCase('cryptosoft0')
37308fca7a5SJohn-Mark Gurneyaesni = GenTestCase('aesni0')
3746720b890SJohn Baldwinccr = GenTestCase('ccr0')
375844d9543SConrad Meyerccp = GenTestCase('ccp0')
37608fca7a5SJohn-Mark Gurney
37708fca7a5SJohn-Mark Gurneyif __name__ == '__main__':
37808fca7a5SJohn-Mark Gurney	unittest.main()
379