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 33d99c2cecSEnji Cooper 34d99c2cecSEnji Cooperimport binascii 35a317fb03SConrad Meyerimport errno 3608fca7a5SJohn-Mark Gurneyimport cryptodev 3708fca7a5SJohn-Mark Gurneyimport itertools 3808fca7a5SJohn-Mark Gurneyimport os 3908fca7a5SJohn-Mark Gurneyimport struct 4008fca7a5SJohn-Mark Gurneyimport unittest 4108fca7a5SJohn-Mark Gurneyfrom cryptodev import * 4208fca7a5SJohn-Mark Gurneyfrom glob import iglob 4308fca7a5SJohn-Mark Gurney 4408fca7a5SJohn-Mark Gurneykatdir = '/usr/local/share/nist-kat' 4508fca7a5SJohn-Mark Gurney 4608fca7a5SJohn-Mark Gurneydef katg(base, glob): 47aeb5c8e6SJohn Baldwin assert os.path.exists(katdir), "Please 'pkg install nist-kat'" 48aeb5c8e6SJohn Baldwin if not os.path.exists(os.path.join(katdir, base)): 49aeb5c8e6SJohn Baldwin raise unittest.SkipTest("Missing %s test vectors" % (base)) 5008fca7a5SJohn-Mark Gurney return iglob(os.path.join(katdir, base, glob)) 5108fca7a5SJohn-Mark Gurney 52844d9543SConrad Meyeraesmodules = [ 'cryptosoft0', 'aesni0', 'ccr0', 'ccp0' ] 5308fca7a5SJohn-Mark Gurneydesmodules = [ 'cryptosoft0', ] 54844d9543SConrad Meyershamodules = [ 'cryptosoft0', 'aesni0', 'ccr0', 'ccp0' ] 5508fca7a5SJohn-Mark Gurney 5608fca7a5SJohn-Mark Gurneydef GenTestCase(cname): 5708fca7a5SJohn-Mark Gurney try: 5808fca7a5SJohn-Mark Gurney crid = cryptodev.Crypto.findcrid(cname) 5908fca7a5SJohn-Mark Gurney except IOError: 6008fca7a5SJohn-Mark Gurney return None 6108fca7a5SJohn-Mark Gurney 6208fca7a5SJohn-Mark Gurney class GendCryptoTestCase(unittest.TestCase): 6308fca7a5SJohn-Mark Gurney ############### 6408fca7a5SJohn-Mark Gurney ##### AES ##### 6508fca7a5SJohn-Mark Gurney ############### 66c091d0d9SJohn Baldwin @unittest.skipIf(cname not in aesmodules, 'skipping AES-XTS on %s' % (cname)) 6708fca7a5SJohn-Mark Gurney def test_xts(self): 6808fca7a5SJohn-Mark Gurney for i in katg('XTSTestVectors/format tweak value input - data unit seq no', '*.rsp'): 6908fca7a5SJohn-Mark Gurney self.runXTS(i, cryptodev.CRYPTO_AES_XTS) 7008fca7a5SJohn-Mark Gurney 71c091d0d9SJohn Baldwin @unittest.skipIf(cname not in aesmodules, 'skipping AES-CBC on %s' % (cname)) 7208fca7a5SJohn-Mark Gurney def test_cbc(self): 7308fca7a5SJohn-Mark Gurney for i in katg('KAT_AES', 'CBC[GKV]*.rsp'): 7408fca7a5SJohn-Mark Gurney self.runCBC(i) 7508fca7a5SJohn-Mark Gurney 76151f0ca8SJohn Baldwin @unittest.skipIf(cname not in aesmodules, 'skipping AES-CCM on %s' % (cname)) 77151f0ca8SJohn Baldwin def test_ccm(self): 78151f0ca8SJohn Baldwin for i in katg('ccmtestvectors', 'V*.rsp'): 79151f0ca8SJohn Baldwin self.runCCMEncrypt(i) 80151f0ca8SJohn Baldwin 81151f0ca8SJohn Baldwin for i in katg('ccmtestvectors', 'D*.rsp'): 82151f0ca8SJohn Baldwin self.runCCMDecrypt(i) 83151f0ca8SJohn Baldwin 84c091d0d9SJohn Baldwin @unittest.skipIf(cname not in aesmodules, 'skipping AES-GCM on %s' % (cname)) 8508fca7a5SJohn-Mark Gurney def test_gcm(self): 8608fca7a5SJohn-Mark Gurney for i in katg('gcmtestvectors', 'gcmEncrypt*'): 8708fca7a5SJohn-Mark Gurney self.runGCM(i, 'ENCRYPT') 8808fca7a5SJohn-Mark Gurney 8908fca7a5SJohn-Mark Gurney for i in katg('gcmtestvectors', 'gcmDecrypt*'): 9008fca7a5SJohn-Mark Gurney self.runGCM(i, 'DECRYPT') 9108fca7a5SJohn-Mark Gurney 9208fca7a5SJohn-Mark Gurney _gmacsizes = { 32: cryptodev.CRYPTO_AES_256_NIST_GMAC, 9308fca7a5SJohn-Mark Gurney 24: cryptodev.CRYPTO_AES_192_NIST_GMAC, 9408fca7a5SJohn-Mark Gurney 16: cryptodev.CRYPTO_AES_128_NIST_GMAC, 9508fca7a5SJohn-Mark Gurney } 9608fca7a5SJohn-Mark Gurney def runGCM(self, fname, mode): 9708fca7a5SJohn-Mark Gurney curfun = None 9808fca7a5SJohn-Mark Gurney if mode == 'ENCRYPT': 9908fca7a5SJohn-Mark Gurney swapptct = False 10008fca7a5SJohn-Mark Gurney curfun = Crypto.encrypt 10108fca7a5SJohn-Mark Gurney elif mode == 'DECRYPT': 10208fca7a5SJohn-Mark Gurney swapptct = True 10308fca7a5SJohn-Mark Gurney curfun = Crypto.decrypt 10408fca7a5SJohn-Mark Gurney else: 105d86680b0SEnji Cooper raise RuntimeError('unknown mode: %r' % repr(mode)) 10608fca7a5SJohn-Mark Gurney 10708fca7a5SJohn-Mark Gurney for bogusmode, lines in cryptodev.KATParser(fname, 10808fca7a5SJohn-Mark Gurney [ 'Count', 'Key', 'IV', 'CT', 'AAD', 'Tag', 'PT', ]): 10908fca7a5SJohn-Mark Gurney for data in lines: 11008fca7a5SJohn-Mark Gurney curcnt = int(data['Count']) 111d99c2cecSEnji Cooper cipherkey = binascii.unhexlify(data['Key']) 112d99c2cecSEnji Cooper iv = binascii.unhexlify(data['IV']) 113d99c2cecSEnji Cooper aad = binascii.unhexlify(data['AAD']) 114d99c2cecSEnji Cooper tag = binascii.unhexlify(data['Tag']) 11508fca7a5SJohn-Mark Gurney if 'FAIL' not in data: 116d99c2cecSEnji Cooper pt = binascii.unhexlify(data['PT']) 117d99c2cecSEnji Cooper ct = binascii.unhexlify(data['CT']) 11808fca7a5SJohn-Mark Gurney 11908fca7a5SJohn-Mark Gurney if len(iv) != 12: 12008fca7a5SJohn-Mark Gurney # XXX - isn't supported 12108fca7a5SJohn-Mark Gurney continue 12208fca7a5SJohn-Mark Gurney 123844d9543SConrad Meyer try: 12408fca7a5SJohn-Mark Gurney c = Crypto(cryptodev.CRYPTO_AES_NIST_GCM_16, 12508fca7a5SJohn-Mark Gurney cipherkey, 12608fca7a5SJohn-Mark Gurney mac=self._gmacsizes[len(cipherkey)], 127de0f7dcaSJohn Baldwin mackey=cipherkey, crid=crid, 128de0f7dcaSJohn Baldwin maclen=16) 129b106e0fcSEnji Cooper except EnvironmentError as e: 130844d9543SConrad Meyer # Can't test algorithms the driver does not support. 131844d9543SConrad Meyer if e.errno != errno.EOPNOTSUPP: 132844d9543SConrad Meyer raise 133844d9543SConrad Meyer continue 13408fca7a5SJohn-Mark Gurney 13508fca7a5SJohn-Mark Gurney if mode == 'ENCRYPT': 136844d9543SConrad Meyer try: 13708fca7a5SJohn-Mark Gurney rct, rtag = c.encrypt(pt, iv, aad) 138b106e0fcSEnji Cooper except EnvironmentError as e: 139844d9543SConrad Meyer # Can't test inputs the driver does not support. 140844d9543SConrad Meyer if e.errno != errno.EINVAL: 141844d9543SConrad Meyer raise 142844d9543SConrad Meyer continue 14308fca7a5SJohn-Mark Gurney rtag = rtag[:len(tag)] 144d99c2cecSEnji Cooper data['rct'] = binascii.hexlify(rct) 145d99c2cecSEnji Cooper data['rtag'] = binascii.hexlify(rtag) 146d86680b0SEnji Cooper self.assertEqual(rct, ct, repr(data)) 147d86680b0SEnji Cooper self.assertEqual(rtag, tag, repr(data)) 14808fca7a5SJohn-Mark Gurney else: 14908fca7a5SJohn-Mark Gurney if len(tag) != 16: 15008fca7a5SJohn-Mark Gurney continue 15108fca7a5SJohn-Mark Gurney args = (ct, iv, aad, tag) 15208fca7a5SJohn-Mark Gurney if 'FAIL' in data: 15308fca7a5SJohn-Mark Gurney self.assertRaises(IOError, 15408fca7a5SJohn-Mark Gurney c.decrypt, *args) 15508fca7a5SJohn-Mark Gurney else: 156844d9543SConrad Meyer try: 15708fca7a5SJohn-Mark Gurney rpt, rtag = c.decrypt(*args) 158b106e0fcSEnji Cooper except EnvironmentError as e: 159844d9543SConrad Meyer # Can't test inputs the driver does not support. 160844d9543SConrad Meyer if e.errno != errno.EINVAL: 161844d9543SConrad Meyer raise 162844d9543SConrad Meyer continue 163d99c2cecSEnji Cooper data['rpt'] = binascii.hexlify(rpt) 164d99c2cecSEnji Cooper data['rtag'] = binascii.hexlify(rtag) 16508fca7a5SJohn-Mark Gurney self.assertEqual(rpt, pt, 166d86680b0SEnji Cooper repr(data)) 16708fca7a5SJohn-Mark Gurney 16808fca7a5SJohn-Mark Gurney def runCBC(self, fname): 16908fca7a5SJohn-Mark Gurney curfun = None 17008fca7a5SJohn-Mark Gurney for mode, lines in cryptodev.KATParser(fname, 17108fca7a5SJohn-Mark Gurney [ 'COUNT', 'KEY', 'IV', 'PLAINTEXT', 'CIPHERTEXT', ]): 17208fca7a5SJohn-Mark Gurney if mode == 'ENCRYPT': 17308fca7a5SJohn-Mark Gurney swapptct = False 17408fca7a5SJohn-Mark Gurney curfun = Crypto.encrypt 17508fca7a5SJohn-Mark Gurney elif mode == 'DECRYPT': 17608fca7a5SJohn-Mark Gurney swapptct = True 17708fca7a5SJohn-Mark Gurney curfun = Crypto.decrypt 17808fca7a5SJohn-Mark Gurney else: 179d86680b0SEnji Cooper raise RuntimeError('unknown mode: %r' % repr(mode)) 18008fca7a5SJohn-Mark Gurney 18108fca7a5SJohn-Mark Gurney for data in lines: 18208fca7a5SJohn-Mark Gurney curcnt = int(data['COUNT']) 183d99c2cecSEnji Cooper cipherkey = binascii.unhexlify(data['KEY']) 184d99c2cecSEnji Cooper iv = binascii.unhexlify(data['IV']) 185d99c2cecSEnji Cooper pt = binascii.unhexlify(data['PLAINTEXT']) 186d99c2cecSEnji Cooper ct = binascii.unhexlify(data['CIPHERTEXT']) 18708fca7a5SJohn-Mark Gurney 18808fca7a5SJohn-Mark Gurney if swapptct: 18908fca7a5SJohn-Mark Gurney pt, ct = ct, pt 19008fca7a5SJohn-Mark Gurney # run the fun 19108fca7a5SJohn-Mark Gurney c = Crypto(cryptodev.CRYPTO_AES_CBC, cipherkey, crid=crid) 19208fca7a5SJohn-Mark Gurney r = curfun(c, pt, iv) 19308fca7a5SJohn-Mark Gurney self.assertEqual(r, ct) 19408fca7a5SJohn-Mark Gurney 19508fca7a5SJohn-Mark Gurney def runXTS(self, fname, meth): 19608fca7a5SJohn-Mark Gurney curfun = None 19708fca7a5SJohn-Mark Gurney for mode, lines in cryptodev.KATParser(fname, 19808fca7a5SJohn-Mark Gurney [ 'COUNT', 'DataUnitLen', 'Key', 'DataUnitSeqNumber', 'PT', 19908fca7a5SJohn-Mark Gurney 'CT' ]): 20008fca7a5SJohn-Mark Gurney if mode == 'ENCRYPT': 20108fca7a5SJohn-Mark Gurney swapptct = False 20208fca7a5SJohn-Mark Gurney curfun = Crypto.encrypt 20308fca7a5SJohn-Mark Gurney elif mode == 'DECRYPT': 20408fca7a5SJohn-Mark Gurney swapptct = True 20508fca7a5SJohn-Mark Gurney curfun = Crypto.decrypt 20608fca7a5SJohn-Mark Gurney else: 207d86680b0SEnji Cooper raise RuntimeError('unknown mode: %r' % repr(mode)) 20808fca7a5SJohn-Mark Gurney 20908fca7a5SJohn-Mark Gurney for data in lines: 21008fca7a5SJohn-Mark Gurney curcnt = int(data['COUNT']) 21108fca7a5SJohn-Mark Gurney nbits = int(data['DataUnitLen']) 212d99c2cecSEnji Cooper cipherkey = binascii.unhexlify(data['Key']) 21308fca7a5SJohn-Mark Gurney iv = struct.pack('QQ', int(data['DataUnitSeqNumber']), 0) 214d99c2cecSEnji Cooper pt = binascii.unhexlify(data['PT']) 215d99c2cecSEnji Cooper ct = binascii.unhexlify(data['CT']) 21608fca7a5SJohn-Mark Gurney 21708fca7a5SJohn-Mark Gurney if nbits % 128 != 0: 21808fca7a5SJohn-Mark Gurney # XXX - mark as skipped 21908fca7a5SJohn-Mark Gurney continue 22008fca7a5SJohn-Mark Gurney if swapptct: 22108fca7a5SJohn-Mark Gurney pt, ct = ct, pt 22208fca7a5SJohn-Mark Gurney # run the fun 223844d9543SConrad Meyer try: 22408fca7a5SJohn-Mark Gurney c = Crypto(meth, cipherkey, crid=crid) 22508fca7a5SJohn-Mark Gurney r = curfun(c, pt, iv) 226b106e0fcSEnji Cooper except EnvironmentError as e: 227844d9543SConrad Meyer # Can't test hashes the driver does not support. 228844d9543SConrad Meyer if e.errno != errno.EOPNOTSUPP: 229844d9543SConrad Meyer raise 230844d9543SConrad Meyer continue 23108fca7a5SJohn-Mark Gurney self.assertEqual(r, ct) 23208fca7a5SJohn-Mark Gurney 233151f0ca8SJohn Baldwin def runCCMEncrypt(self, fname): 234151f0ca8SJohn Baldwin for data in cryptodev.KATCCMParser(fname): 235151f0ca8SJohn Baldwin Nlen = int(data['Nlen']) 236151f0ca8SJohn Baldwin if Nlen != 12: 237151f0ca8SJohn Baldwin # OCF only supports 12 byte IVs 238151f0ca8SJohn Baldwin continue 239d99c2cecSEnji Cooper key = binascii.unhexlify(data['Key']) 240d99c2cecSEnji Cooper nonce = binascii.unhexlify(data['Nonce']) 241151f0ca8SJohn Baldwin Alen = int(data['Alen']) 242151f0ca8SJohn Baldwin if Alen != 0: 243d99c2cecSEnji Cooper aad = binascii.unhexlify(data['Adata']) 244151f0ca8SJohn Baldwin else: 245151f0ca8SJohn Baldwin aad = None 246d99c2cecSEnji Cooper payload = binascii.unhexlify(data['Payload']) 247d99c2cecSEnji Cooper ct = binascii.unhexlify(data['CT']) 248151f0ca8SJohn Baldwin 249151f0ca8SJohn Baldwin try: 250151f0ca8SJohn Baldwin c = Crypto(crid=crid, 251151f0ca8SJohn Baldwin cipher=cryptodev.CRYPTO_AES_CCM_16, 252151f0ca8SJohn Baldwin key=key, 253151f0ca8SJohn Baldwin mac=cryptodev.CRYPTO_AES_CCM_CBC_MAC, 254151f0ca8SJohn Baldwin mackey=key, maclen=16) 255151f0ca8SJohn Baldwin r, tag = Crypto.encrypt(c, payload, 256151f0ca8SJohn Baldwin nonce, aad) 257b106e0fcSEnji Cooper except EnvironmentError as e: 258151f0ca8SJohn Baldwin if e.errno != errno.EOPNOTSUPP: 259151f0ca8SJohn Baldwin raise 260151f0ca8SJohn Baldwin continue 261151f0ca8SJohn Baldwin 262151f0ca8SJohn Baldwin out = r + tag 263151f0ca8SJohn Baldwin self.assertEqual(out, ct, 264151f0ca8SJohn Baldwin "Count " + data['Count'] + " Actual: " + \ 265*e8b4bbdfSEnji Cooper repr(binascii.hexlify(out)) + " Expected: " + \ 266151f0ca8SJohn Baldwin repr(data) + " on " + cname) 267151f0ca8SJohn Baldwin 268151f0ca8SJohn Baldwin def runCCMDecrypt(self, fname): 269151f0ca8SJohn Baldwin # XXX: Note that all of the current CCM 270151f0ca8SJohn Baldwin # decryption test vectors use IV and tag sizes 271151f0ca8SJohn Baldwin # that aren't supported by OCF none of the 272151f0ca8SJohn Baldwin # tests are actually ran. 273151f0ca8SJohn Baldwin for data in cryptodev.KATCCMParser(fname): 274151f0ca8SJohn Baldwin Nlen = int(data['Nlen']) 275151f0ca8SJohn Baldwin if Nlen != 12: 276151f0ca8SJohn Baldwin # OCF only supports 12 byte IVs 277151f0ca8SJohn Baldwin continue 278151f0ca8SJohn Baldwin Tlen = int(data['Tlen']) 279151f0ca8SJohn Baldwin if Tlen != 16: 280151f0ca8SJohn Baldwin # OCF only supports 16 byte tags 281151f0ca8SJohn Baldwin continue 282d99c2cecSEnji Cooper key = binascii.unhexlify(data['Key']) 283d99c2cecSEnji Cooper nonce = binascii.unhexlify(data['Nonce']) 284151f0ca8SJohn Baldwin Alen = int(data['Alen']) 285151f0ca8SJohn Baldwin if Alen != 0: 286d99c2cecSEnji Cooper aad = binascii.unhexlify(data['Adata']) 287151f0ca8SJohn Baldwin else: 288151f0ca8SJohn Baldwin aad = None 289d99c2cecSEnji Cooper ct = binascii.unhexlify(data['CT']) 290151f0ca8SJohn Baldwin tag = ct[-16:] 291151f0ca8SJohn Baldwin ct = ct[:-16] 292151f0ca8SJohn Baldwin 293151f0ca8SJohn Baldwin try: 294151f0ca8SJohn Baldwin c = Crypto(crid=crid, 295151f0ca8SJohn Baldwin cipher=cryptodev.CRYPTO_AES_CCM_16, 296151f0ca8SJohn Baldwin key=key, 297151f0ca8SJohn Baldwin mac=cryptodev.CRYPTO_AES_CCM_CBC_MAC, 298151f0ca8SJohn Baldwin mackey=key, maclen=16) 299b106e0fcSEnji Cooper except EnvironmentError as e: 300151f0ca8SJohn Baldwin if e.errno != errno.EOPNOTSUPP: 301151f0ca8SJohn Baldwin raise 302151f0ca8SJohn Baldwin continue 303151f0ca8SJohn Baldwin 304151f0ca8SJohn Baldwin if data['Result'] == 'Fail': 305151f0ca8SJohn Baldwin self.assertRaises(IOError, 306151f0ca8SJohn Baldwin c.decrypt, payload, nonce, aad, tag) 307151f0ca8SJohn Baldwin else: 308151f0ca8SJohn Baldwin r = Crypto.decrypt(c, payload, nonce, 309151f0ca8SJohn Baldwin aad, tag) 310151f0ca8SJohn Baldwin 311d99c2cecSEnji Cooper payload = binascii.unhexlify(data['Payload']) 3122a96ae15SEnji Cooper plen = int(data('Plen')) 313151f0ca8SJohn Baldwin payload = payload[:plen] 314151f0ca8SJohn Baldwin self.assertEqual(r, payload, 315151f0ca8SJohn Baldwin "Count " + data['Count'] + \ 316*e8b4bbdfSEnji Cooper " Actual: " + repr(binascii.hexlify(r)) + \ 317151f0ca8SJohn Baldwin " Expected: " + repr(data) + \ 318151f0ca8SJohn Baldwin " on " + cname) 319151f0ca8SJohn Baldwin 32008fca7a5SJohn-Mark Gurney ############### 32108fca7a5SJohn-Mark Gurney ##### DES ##### 32208fca7a5SJohn-Mark Gurney ############### 323d86680b0SEnji Cooper @unittest.skipIf(cname not in desmodules, 'skipping DES on %s' % (cname)) 32408fca7a5SJohn-Mark Gurney def test_tdes(self): 32508fca7a5SJohn-Mark Gurney for i in katg('KAT_TDES', 'TCBC[a-z]*.rsp'): 32608fca7a5SJohn-Mark Gurney self.runTDES(i) 32708fca7a5SJohn-Mark Gurney 32808fca7a5SJohn-Mark Gurney def runTDES(self, fname): 32908fca7a5SJohn-Mark Gurney curfun = None 33008fca7a5SJohn-Mark Gurney for mode, lines in cryptodev.KATParser(fname, 33108fca7a5SJohn-Mark Gurney [ 'COUNT', 'KEYs', 'IV', 'PLAINTEXT', 'CIPHERTEXT', ]): 33208fca7a5SJohn-Mark Gurney if mode == 'ENCRYPT': 33308fca7a5SJohn-Mark Gurney swapptct = False 33408fca7a5SJohn-Mark Gurney curfun = Crypto.encrypt 33508fca7a5SJohn-Mark Gurney elif mode == 'DECRYPT': 33608fca7a5SJohn-Mark Gurney swapptct = True 33708fca7a5SJohn-Mark Gurney curfun = Crypto.decrypt 33808fca7a5SJohn-Mark Gurney else: 339d86680b0SEnji Cooper raise RuntimeError('unknown mode: %r' % repr(mode)) 34008fca7a5SJohn-Mark Gurney 34108fca7a5SJohn-Mark Gurney for data in lines: 34208fca7a5SJohn-Mark Gurney curcnt = int(data['COUNT']) 34308fca7a5SJohn-Mark Gurney key = data['KEYs'] * 3 344d99c2cecSEnji Cooper cipherkey = binascii.unhexlify(key) 345d99c2cecSEnji Cooper iv = binascii.unhexlify(data['IV']) 346d99c2cecSEnji Cooper pt = binascii.unhexlify(data['PLAINTEXT']) 347d99c2cecSEnji Cooper ct = binascii.unhexlify(data['CIPHERTEXT']) 34808fca7a5SJohn-Mark Gurney 34908fca7a5SJohn-Mark Gurney if swapptct: 35008fca7a5SJohn-Mark Gurney pt, ct = ct, pt 35108fca7a5SJohn-Mark Gurney # run the fun 35208fca7a5SJohn-Mark Gurney c = Crypto(cryptodev.CRYPTO_3DES_CBC, cipherkey, crid=crid) 35308fca7a5SJohn-Mark Gurney r = curfun(c, pt, iv) 35408fca7a5SJohn-Mark Gurney self.assertEqual(r, ct) 35508fca7a5SJohn-Mark Gurney 35608fca7a5SJohn-Mark Gurney ############### 35708fca7a5SJohn-Mark Gurney ##### SHA ##### 35808fca7a5SJohn-Mark Gurney ############### 359d86680b0SEnji Cooper @unittest.skipIf(cname not in shamodules, 'skipping SHA on %s' % str(cname)) 36008fca7a5SJohn-Mark Gurney def test_sha(self): 361de0f7dcaSJohn Baldwin for i in katg('shabytetestvectors', 'SHA*Msg.rsp'): 362de0f7dcaSJohn Baldwin self.runSHA(i) 363de0f7dcaSJohn Baldwin 364de0f7dcaSJohn Baldwin def runSHA(self, fname): 365de0f7dcaSJohn Baldwin # Skip SHA512_(224|256) tests 366de0f7dcaSJohn Baldwin if fname.find('SHA512_') != -1: 367de0f7dcaSJohn Baldwin return 368de0f7dcaSJohn Baldwin 369de0f7dcaSJohn Baldwin for hashlength, lines in cryptodev.KATParser(fname, 370de0f7dcaSJohn Baldwin [ 'Len', 'Msg', 'MD' ]): 371de0f7dcaSJohn Baldwin # E.g., hashlength will be "L=20" (bytes) 372de0f7dcaSJohn Baldwin hashlen = int(hashlength.split("=")[1]) 373de0f7dcaSJohn Baldwin 374de0f7dcaSJohn Baldwin if hashlen == 20: 375de0f7dcaSJohn Baldwin alg = cryptodev.CRYPTO_SHA1 376de0f7dcaSJohn Baldwin elif hashlen == 28: 377de0f7dcaSJohn Baldwin alg = cryptodev.CRYPTO_SHA2_224 378de0f7dcaSJohn Baldwin elif hashlen == 32: 379de0f7dcaSJohn Baldwin alg = cryptodev.CRYPTO_SHA2_256 380de0f7dcaSJohn Baldwin elif hashlen == 48: 381de0f7dcaSJohn Baldwin alg = cryptodev.CRYPTO_SHA2_384 382de0f7dcaSJohn Baldwin elif hashlen == 64: 383de0f7dcaSJohn Baldwin alg = cryptodev.CRYPTO_SHA2_512 384de0f7dcaSJohn Baldwin else: 385de0f7dcaSJohn Baldwin # Skip unsupported hashes 386de0f7dcaSJohn Baldwin # Slurp remaining input in section 387de0f7dcaSJohn Baldwin for data in lines: 388de0f7dcaSJohn Baldwin continue 389de0f7dcaSJohn Baldwin continue 390de0f7dcaSJohn Baldwin 391de0f7dcaSJohn Baldwin for data in lines: 392d99c2cecSEnji Cooper msg = binascii.unhexlify(data['Msg']) 393de0f7dcaSJohn Baldwin msg = msg[:int(data['Len'])] 394d99c2cecSEnji Cooper md = binascii.unhexlify(data['MD']) 395de0f7dcaSJohn Baldwin 396de0f7dcaSJohn Baldwin try: 397de0f7dcaSJohn Baldwin c = Crypto(mac=alg, crid=crid, 398de0f7dcaSJohn Baldwin maclen=hashlen) 399b106e0fcSEnji Cooper except EnvironmentError as e: 400de0f7dcaSJohn Baldwin # Can't test hashes the driver does not support. 401de0f7dcaSJohn Baldwin if e.errno != errno.EOPNOTSUPP: 402de0f7dcaSJohn Baldwin raise 403de0f7dcaSJohn Baldwin continue 404de0f7dcaSJohn Baldwin 405de0f7dcaSJohn Baldwin _, r = c.encrypt(msg, iv="") 406de0f7dcaSJohn Baldwin 407de0f7dcaSJohn Baldwin self.assertEqual(r, md, "Actual: " + \ 408*e8b4bbdfSEnji Cooper repr(binascii.hexlify(r)) + " Expected: " + repr(data) + " on " + cname) 40908fca7a5SJohn-Mark Gurney 410c091d0d9SJohn Baldwin @unittest.skipIf(cname not in shamodules, 'skipping SHA-HMAC on %s' % str(cname)) 41108fca7a5SJohn-Mark Gurney def test_sha1hmac(self): 41208fca7a5SJohn-Mark Gurney for i in katg('hmactestvectors', 'HMAC.rsp'): 41308fca7a5SJohn-Mark Gurney self.runSHA1HMAC(i) 41408fca7a5SJohn-Mark Gurney 41508fca7a5SJohn-Mark Gurney def runSHA1HMAC(self, fname): 416005fdbbcSConrad Meyer for hashlength, lines in cryptodev.KATParser(fname, 41708fca7a5SJohn-Mark Gurney [ 'Count', 'Klen', 'Tlen', 'Key', 'Msg', 'Mac' ]): 418005fdbbcSConrad Meyer # E.g., hashlength will be "L=20" (bytes) 419005fdbbcSConrad Meyer hashlen = int(hashlength.split("=")[1]) 420005fdbbcSConrad Meyer 421005fdbbcSConrad Meyer blocksize = None 422005fdbbcSConrad Meyer if hashlen == 20: 423005fdbbcSConrad Meyer alg = cryptodev.CRYPTO_SHA1_HMAC 424005fdbbcSConrad Meyer blocksize = 64 425005fdbbcSConrad Meyer elif hashlen == 28: 426c87ada6aSJohn Baldwin alg = cryptodev.CRYPTO_SHA2_224_HMAC 427c87ada6aSJohn Baldwin blocksize = 64 428005fdbbcSConrad Meyer elif hashlen == 32: 429005fdbbcSConrad Meyer alg = cryptodev.CRYPTO_SHA2_256_HMAC 430005fdbbcSConrad Meyer blocksize = 64 431005fdbbcSConrad Meyer elif hashlen == 48: 432005fdbbcSConrad Meyer alg = cryptodev.CRYPTO_SHA2_384_HMAC 433005fdbbcSConrad Meyer blocksize = 128 434005fdbbcSConrad Meyer elif hashlen == 64: 435005fdbbcSConrad Meyer alg = cryptodev.CRYPTO_SHA2_512_HMAC 436005fdbbcSConrad Meyer blocksize = 128 437005fdbbcSConrad Meyer else: 438005fdbbcSConrad Meyer # Skip unsupported hashes 439005fdbbcSConrad Meyer # Slurp remaining input in section 440005fdbbcSConrad Meyer for data in lines: 441005fdbbcSConrad Meyer continue 442005fdbbcSConrad Meyer continue 443005fdbbcSConrad Meyer 44408fca7a5SJohn-Mark Gurney for data in lines: 445d99c2cecSEnji Cooper key = binascii.unhexlify(data['Key']) 446d99c2cecSEnji Cooper msg = binascii.unhexlify(data['Msg']) 447d99c2cecSEnji Cooper mac = binascii.unhexlify(data['Mac']) 448005fdbbcSConrad Meyer tlen = int(data['Tlen']) 44908fca7a5SJohn-Mark Gurney 450005fdbbcSConrad Meyer if len(key) > blocksize: 45108fca7a5SJohn-Mark Gurney continue 45208fca7a5SJohn-Mark Gurney 453a317fb03SConrad Meyer try: 454005fdbbcSConrad Meyer c = Crypto(mac=alg, mackey=key, 455de0f7dcaSJohn Baldwin crid=crid, maclen=hashlen) 456b106e0fcSEnji Cooper except EnvironmentError as e: 457a317fb03SConrad Meyer # Can't test hashes the driver does not support. 458a317fb03SConrad Meyer if e.errno != errno.EOPNOTSUPP: 459a317fb03SConrad Meyer raise 460a317fb03SConrad Meyer continue 46108fca7a5SJohn-Mark Gurney 462005fdbbcSConrad Meyer _, r = c.encrypt(msg, iv="") 463005fdbbcSConrad Meyer 464de0f7dcaSJohn Baldwin self.assertEqual(r[:tlen], mac, "Actual: " + \ 465*e8b4bbdfSEnji Cooper repr(binascii.hexlify(r)) + " Expected: " + repr(data)) 46608fca7a5SJohn-Mark Gurney 46708fca7a5SJohn-Mark Gurney return GendCryptoTestCase 46808fca7a5SJohn-Mark Gurney 46908fca7a5SJohn-Mark Gurneycryptosoft = GenTestCase('cryptosoft0') 47008fca7a5SJohn-Mark Gurneyaesni = GenTestCase('aesni0') 4716720b890SJohn Baldwinccr = GenTestCase('ccr0') 472844d9543SConrad Meyerccp = GenTestCase('ccp0') 47308fca7a5SJohn-Mark Gurney 47408fca7a5SJohn-Mark Gurneyif __name__ == '__main__': 47508fca7a5SJohn-Mark Gurney unittest.main() 476