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. 5f2a34445SEnji Cooper# Copyright 2019 Enji Cooper 608fca7a5SJohn-Mark Gurney# 708fca7a5SJohn-Mark Gurney# This software was developed by John-Mark Gurney under 808fca7a5SJohn-Mark Gurney# the sponsorship from the FreeBSD Foundation. 908fca7a5SJohn-Mark Gurney# Redistribution and use in source and binary forms, with or without 1008fca7a5SJohn-Mark Gurney# modification, are permitted provided that the following conditions 1108fca7a5SJohn-Mark Gurney# are met: 1208fca7a5SJohn-Mark Gurney# 1. Redistributions of source code must retain the above copyright 1308fca7a5SJohn-Mark Gurney# notice, this list of conditions and the following disclaimer. 1408fca7a5SJohn-Mark Gurney# 2. Redistributions in binary form must reproduce the above copyright 1508fca7a5SJohn-Mark Gurney# notice, this list of conditions and the following disclaimer in the 1608fca7a5SJohn-Mark Gurney# documentation and/or other materials provided with the distribution. 1708fca7a5SJohn-Mark Gurney# 1808fca7a5SJohn-Mark Gurney# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1908fca7a5SJohn-Mark Gurney# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2008fca7a5SJohn-Mark Gurney# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2108fca7a5SJohn-Mark Gurney# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2208fca7a5SJohn-Mark Gurney# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2308fca7a5SJohn-Mark Gurney# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2408fca7a5SJohn-Mark Gurney# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2508fca7a5SJohn-Mark Gurney# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2608fca7a5SJohn-Mark Gurney# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2708fca7a5SJohn-Mark Gurney# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2808fca7a5SJohn-Mark Gurney# SUCH DAMAGE. 2908fca7a5SJohn-Mark Gurney# 3008fca7a5SJohn-Mark Gurney# $FreeBSD$ 3108fca7a5SJohn-Mark Gurney# 3208fca7a5SJohn-Mark Gurney 33d86680b0SEnji Cooperfrom __future__ import print_function 34d99c2cecSEnji Cooper 35d99c2cecSEnji Cooperimport binascii 36a317fb03SConrad Meyerimport errno 3708fca7a5SJohn-Mark Gurneyimport cryptodev 3808fca7a5SJohn-Mark Gurneyimport itertools 3908fca7a5SJohn-Mark Gurneyimport os 4008fca7a5SJohn-Mark Gurneyimport struct 4108fca7a5SJohn-Mark Gurneyimport unittest 4208fca7a5SJohn-Mark Gurneyfrom cryptodev import * 4308fca7a5SJohn-Mark Gurneyfrom glob import iglob 4408fca7a5SJohn-Mark Gurney 4508fca7a5SJohn-Mark Gurneykatdir = '/usr/local/share/nist-kat' 4608fca7a5SJohn-Mark Gurney 4708fca7a5SJohn-Mark Gurneydef katg(base, glob): 48aeb5c8e6SJohn Baldwin assert os.path.exists(katdir), "Please 'pkg install nist-kat'" 49aeb5c8e6SJohn Baldwin if not os.path.exists(os.path.join(katdir, base)): 50aeb5c8e6SJohn Baldwin raise unittest.SkipTest("Missing %s test vectors" % (base)) 5108fca7a5SJohn-Mark Gurney return iglob(os.path.join(katdir, base, glob)) 5208fca7a5SJohn-Mark Gurney 53*84a457c6SEnji Cooperaesmodules = [ 'cryptosoft0', 'aesni0', 'armv8crypto0', 'ccr0', 'ccp0' ] 5408fca7a5SJohn-Mark Gurneydesmodules = [ 'cryptosoft0', ] 55*84a457c6SEnji Coopershamodules = [ 'cryptosoft0', 'aesni0', 'armv8crypto0', 'ccr0', 'ccp0' ] 5608fca7a5SJohn-Mark Gurney 5708fca7a5SJohn-Mark Gurneydef GenTestCase(cname): 5808fca7a5SJohn-Mark Gurney try: 5908fca7a5SJohn-Mark Gurney crid = cryptodev.Crypto.findcrid(cname) 6008fca7a5SJohn-Mark Gurney except IOError: 6108fca7a5SJohn-Mark Gurney return None 6208fca7a5SJohn-Mark Gurney 6308fca7a5SJohn-Mark Gurney class GendCryptoTestCase(unittest.TestCase): 6408fca7a5SJohn-Mark Gurney ############### 6508fca7a5SJohn-Mark Gurney ##### AES ##### 6608fca7a5SJohn-Mark Gurney ############### 67c091d0d9SJohn Baldwin @unittest.skipIf(cname not in aesmodules, 'skipping AES-XTS on %s' % (cname)) 6808fca7a5SJohn-Mark Gurney def test_xts(self): 6908fca7a5SJohn-Mark Gurney for i in katg('XTSTestVectors/format tweak value input - data unit seq no', '*.rsp'): 7008fca7a5SJohn-Mark Gurney self.runXTS(i, cryptodev.CRYPTO_AES_XTS) 7108fca7a5SJohn-Mark Gurney 72c091d0d9SJohn Baldwin @unittest.skipIf(cname not in aesmodules, 'skipping AES-CBC on %s' % (cname)) 7308fca7a5SJohn-Mark Gurney def test_cbc(self): 7408fca7a5SJohn-Mark Gurney for i in katg('KAT_AES', 'CBC[GKV]*.rsp'): 7508fca7a5SJohn-Mark Gurney self.runCBC(i) 7608fca7a5SJohn-Mark Gurney 77151f0ca8SJohn Baldwin @unittest.skipIf(cname not in aesmodules, 'skipping AES-CCM on %s' % (cname)) 78151f0ca8SJohn Baldwin def test_ccm(self): 79151f0ca8SJohn Baldwin for i in katg('ccmtestvectors', 'V*.rsp'): 80151f0ca8SJohn Baldwin self.runCCMEncrypt(i) 81151f0ca8SJohn Baldwin 82151f0ca8SJohn Baldwin for i in katg('ccmtestvectors', 'D*.rsp'): 83151f0ca8SJohn Baldwin self.runCCMDecrypt(i) 84151f0ca8SJohn Baldwin 85c091d0d9SJohn Baldwin @unittest.skipIf(cname not in aesmodules, 'skipping AES-GCM on %s' % (cname)) 8608fca7a5SJohn-Mark Gurney def test_gcm(self): 8708fca7a5SJohn-Mark Gurney for i in katg('gcmtestvectors', 'gcmEncrypt*'): 8808fca7a5SJohn-Mark Gurney self.runGCM(i, 'ENCRYPT') 8908fca7a5SJohn-Mark Gurney 9008fca7a5SJohn-Mark Gurney for i in katg('gcmtestvectors', 'gcmDecrypt*'): 9108fca7a5SJohn-Mark Gurney self.runGCM(i, 'DECRYPT') 9208fca7a5SJohn-Mark Gurney 9308fca7a5SJohn-Mark Gurney _gmacsizes = { 32: cryptodev.CRYPTO_AES_256_NIST_GMAC, 9408fca7a5SJohn-Mark Gurney 24: cryptodev.CRYPTO_AES_192_NIST_GMAC, 9508fca7a5SJohn-Mark Gurney 16: cryptodev.CRYPTO_AES_128_NIST_GMAC, 9608fca7a5SJohn-Mark Gurney } 9708fca7a5SJohn-Mark Gurney def runGCM(self, fname, mode): 9808fca7a5SJohn-Mark Gurney curfun = None 9908fca7a5SJohn-Mark Gurney if mode == 'ENCRYPT': 10008fca7a5SJohn-Mark Gurney swapptct = False 10108fca7a5SJohn-Mark Gurney curfun = Crypto.encrypt 10208fca7a5SJohn-Mark Gurney elif mode == 'DECRYPT': 10308fca7a5SJohn-Mark Gurney swapptct = True 10408fca7a5SJohn-Mark Gurney curfun = Crypto.decrypt 10508fca7a5SJohn-Mark Gurney else: 106d86680b0SEnji Cooper raise RuntimeError('unknown mode: %r' % repr(mode)) 10708fca7a5SJohn-Mark Gurney 108a60d9a98SEnji Cooper columns = [ 'Count', 'Key', 'IV', 'CT', 'AAD', 'Tag', 'PT', ] 109a60d9a98SEnji Cooper with cryptodev.KATParser(fname, columns) as parser: 110a60d9a98SEnji Cooper self.runGCMWithParser(parser, mode) 111a60d9a98SEnji Cooper 112a60d9a98SEnji Cooper def runGCMWithParser(self, parser, mode): 113a60d9a98SEnji Cooper for _, lines in next(parser): 11408fca7a5SJohn-Mark Gurney for data in lines: 11508fca7a5SJohn-Mark Gurney curcnt = int(data['Count']) 116d99c2cecSEnji Cooper cipherkey = binascii.unhexlify(data['Key']) 117d99c2cecSEnji Cooper iv = binascii.unhexlify(data['IV']) 118d99c2cecSEnji Cooper aad = binascii.unhexlify(data['AAD']) 119d99c2cecSEnji Cooper tag = binascii.unhexlify(data['Tag']) 12008fca7a5SJohn-Mark Gurney if 'FAIL' not in data: 121d99c2cecSEnji Cooper pt = binascii.unhexlify(data['PT']) 122d99c2cecSEnji Cooper ct = binascii.unhexlify(data['CT']) 12308fca7a5SJohn-Mark Gurney 12408fca7a5SJohn-Mark Gurney if len(iv) != 12: 12508fca7a5SJohn-Mark Gurney # XXX - isn't supported 12608fca7a5SJohn-Mark Gurney continue 12708fca7a5SJohn-Mark Gurney 128844d9543SConrad Meyer try: 12908fca7a5SJohn-Mark Gurney c = Crypto(cryptodev.CRYPTO_AES_NIST_GCM_16, 13008fca7a5SJohn-Mark Gurney cipherkey, 13108fca7a5SJohn-Mark Gurney mac=self._gmacsizes[len(cipherkey)], 132de0f7dcaSJohn Baldwin mackey=cipherkey, crid=crid, 133de0f7dcaSJohn Baldwin maclen=16) 134b106e0fcSEnji Cooper except EnvironmentError as e: 135844d9543SConrad Meyer # Can't test algorithms the driver does not support. 136844d9543SConrad Meyer if e.errno != errno.EOPNOTSUPP: 137844d9543SConrad Meyer raise 138844d9543SConrad Meyer continue 13908fca7a5SJohn-Mark Gurney 14008fca7a5SJohn-Mark Gurney if mode == 'ENCRYPT': 141844d9543SConrad Meyer try: 14208fca7a5SJohn-Mark Gurney rct, rtag = c.encrypt(pt, iv, aad) 143b106e0fcSEnji Cooper except EnvironmentError as e: 144844d9543SConrad Meyer # Can't test inputs the driver does not support. 145844d9543SConrad Meyer if e.errno != errno.EINVAL: 146844d9543SConrad Meyer raise 147844d9543SConrad Meyer continue 14808fca7a5SJohn-Mark Gurney rtag = rtag[:len(tag)] 149d99c2cecSEnji Cooper data['rct'] = binascii.hexlify(rct) 150d99c2cecSEnji Cooper data['rtag'] = binascii.hexlify(rtag) 151d86680b0SEnji Cooper self.assertEqual(rct, ct, repr(data)) 152d86680b0SEnji Cooper self.assertEqual(rtag, tag, repr(data)) 15308fca7a5SJohn-Mark Gurney else: 15408fca7a5SJohn-Mark Gurney if len(tag) != 16: 15508fca7a5SJohn-Mark Gurney continue 15608fca7a5SJohn-Mark Gurney args = (ct, iv, aad, tag) 15708fca7a5SJohn-Mark Gurney if 'FAIL' in data: 15808fca7a5SJohn-Mark Gurney self.assertRaises(IOError, 15908fca7a5SJohn-Mark Gurney c.decrypt, *args) 16008fca7a5SJohn-Mark Gurney else: 161844d9543SConrad Meyer try: 16208fca7a5SJohn-Mark Gurney rpt, rtag = c.decrypt(*args) 163b106e0fcSEnji Cooper except EnvironmentError as e: 164844d9543SConrad Meyer # Can't test inputs the driver does not support. 165844d9543SConrad Meyer if e.errno != errno.EINVAL: 166844d9543SConrad Meyer raise 167844d9543SConrad Meyer continue 168d99c2cecSEnji Cooper data['rpt'] = binascii.hexlify(rpt) 169d99c2cecSEnji Cooper data['rtag'] = binascii.hexlify(rtag) 17008fca7a5SJohn-Mark Gurney self.assertEqual(rpt, pt, 171d86680b0SEnji Cooper repr(data)) 17208fca7a5SJohn-Mark Gurney 17308fca7a5SJohn-Mark Gurney def runCBC(self, fname): 174a60d9a98SEnji Cooper columns = [ 'COUNT', 'KEY', 'IV', 'PLAINTEXT', 'CIPHERTEXT', ] 175a60d9a98SEnji Cooper with cryptodev.KATParser(fname, columns) as parser: 176a60d9a98SEnji Cooper self.runCBCWithParser(parser) 177a60d9a98SEnji Cooper 178a60d9a98SEnji Cooper def runCBCWithParser(self, parser): 17908fca7a5SJohn-Mark Gurney curfun = None 180a60d9a98SEnji Cooper for mode, lines in next(parser): 18108fca7a5SJohn-Mark Gurney if mode == 'ENCRYPT': 18208fca7a5SJohn-Mark Gurney swapptct = False 18308fca7a5SJohn-Mark Gurney curfun = Crypto.encrypt 18408fca7a5SJohn-Mark Gurney elif mode == 'DECRYPT': 18508fca7a5SJohn-Mark Gurney swapptct = True 18608fca7a5SJohn-Mark Gurney curfun = Crypto.decrypt 18708fca7a5SJohn-Mark Gurney else: 188d86680b0SEnji Cooper raise RuntimeError('unknown mode: %r' % repr(mode)) 18908fca7a5SJohn-Mark Gurney 19008fca7a5SJohn-Mark Gurney for data in lines: 19108fca7a5SJohn-Mark Gurney curcnt = int(data['COUNT']) 192d99c2cecSEnji Cooper cipherkey = binascii.unhexlify(data['KEY']) 193d99c2cecSEnji Cooper iv = binascii.unhexlify(data['IV']) 194d99c2cecSEnji Cooper pt = binascii.unhexlify(data['PLAINTEXT']) 195d99c2cecSEnji Cooper ct = binascii.unhexlify(data['CIPHERTEXT']) 19608fca7a5SJohn-Mark Gurney 19708fca7a5SJohn-Mark Gurney if swapptct: 19808fca7a5SJohn-Mark Gurney pt, ct = ct, pt 19908fca7a5SJohn-Mark Gurney # run the fun 20008fca7a5SJohn-Mark Gurney c = Crypto(cryptodev.CRYPTO_AES_CBC, cipherkey, crid=crid) 20108fca7a5SJohn-Mark Gurney r = curfun(c, pt, iv) 20208fca7a5SJohn-Mark Gurney self.assertEqual(r, ct) 20308fca7a5SJohn-Mark Gurney 20408fca7a5SJohn-Mark Gurney def runXTS(self, fname, meth): 205a60d9a98SEnji Cooper columns = [ 'COUNT', 'DataUnitLen', 'Key', 'DataUnitSeqNumber', 'PT', 206a60d9a98SEnji Cooper 'CT'] 207a60d9a98SEnji Cooper with cryptodev.KATParser(fname, columns) as parser: 208a60d9a98SEnji Cooper self.runXTSWithParser(parser, meth) 209a60d9a98SEnji Cooper 210a60d9a98SEnji Cooper def runXTSWithParser(self, parser, meth): 21108fca7a5SJohn-Mark Gurney curfun = None 212a60d9a98SEnji Cooper for mode, lines in next(parser): 21308fca7a5SJohn-Mark Gurney if mode == 'ENCRYPT': 21408fca7a5SJohn-Mark Gurney swapptct = False 21508fca7a5SJohn-Mark Gurney curfun = Crypto.encrypt 21608fca7a5SJohn-Mark Gurney elif mode == 'DECRYPT': 21708fca7a5SJohn-Mark Gurney swapptct = True 21808fca7a5SJohn-Mark Gurney curfun = Crypto.decrypt 21908fca7a5SJohn-Mark Gurney else: 220d86680b0SEnji Cooper raise RuntimeError('unknown mode: %r' % repr(mode)) 22108fca7a5SJohn-Mark Gurney 22208fca7a5SJohn-Mark Gurney for data in lines: 22308fca7a5SJohn-Mark Gurney curcnt = int(data['COUNT']) 22408fca7a5SJohn-Mark Gurney nbits = int(data['DataUnitLen']) 225d99c2cecSEnji Cooper cipherkey = binascii.unhexlify(data['Key']) 22608fca7a5SJohn-Mark Gurney iv = struct.pack('QQ', int(data['DataUnitSeqNumber']), 0) 227d99c2cecSEnji Cooper pt = binascii.unhexlify(data['PT']) 228d99c2cecSEnji Cooper ct = binascii.unhexlify(data['CT']) 22908fca7a5SJohn-Mark Gurney 23008fca7a5SJohn-Mark Gurney if nbits % 128 != 0: 23108fca7a5SJohn-Mark Gurney # XXX - mark as skipped 23208fca7a5SJohn-Mark Gurney continue 23308fca7a5SJohn-Mark Gurney if swapptct: 23408fca7a5SJohn-Mark Gurney pt, ct = ct, pt 23508fca7a5SJohn-Mark Gurney # run the fun 236844d9543SConrad Meyer try: 23708fca7a5SJohn-Mark Gurney c = Crypto(meth, cipherkey, crid=crid) 23808fca7a5SJohn-Mark Gurney r = curfun(c, pt, iv) 239b106e0fcSEnji Cooper except EnvironmentError as e: 240844d9543SConrad Meyer # Can't test hashes the driver does not support. 241844d9543SConrad Meyer if e.errno != errno.EOPNOTSUPP: 242844d9543SConrad Meyer raise 243844d9543SConrad Meyer continue 24408fca7a5SJohn-Mark Gurney self.assertEqual(r, ct) 24508fca7a5SJohn-Mark Gurney 246151f0ca8SJohn Baldwin def runCCMEncrypt(self, fname): 247a60d9a98SEnji Cooper with cryptodev.KATCCMParser(fname) as parser: 248a60d9a98SEnji Cooper self.runCCMEncryptWithParser(parser) 249a60d9a98SEnji Cooper 250a60d9a98SEnji Cooper def runCCMEncryptWithParser(self, parser): 251a60d9a98SEnji Cooper for data in next(parser): 252151f0ca8SJohn Baldwin Nlen = int(data['Nlen']) 253151f0ca8SJohn Baldwin if Nlen != 12: 254151f0ca8SJohn Baldwin # OCF only supports 12 byte IVs 255151f0ca8SJohn Baldwin continue 256d99c2cecSEnji Cooper key = binascii.unhexlify(data['Key']) 257d99c2cecSEnji Cooper nonce = binascii.unhexlify(data['Nonce']) 258151f0ca8SJohn Baldwin Alen = int(data['Alen']) 259151f0ca8SJohn Baldwin if Alen != 0: 260d99c2cecSEnji Cooper aad = binascii.unhexlify(data['Adata']) 261151f0ca8SJohn Baldwin else: 262151f0ca8SJohn Baldwin aad = None 263d99c2cecSEnji Cooper payload = binascii.unhexlify(data['Payload']) 264d99c2cecSEnji Cooper ct = binascii.unhexlify(data['CT']) 265151f0ca8SJohn Baldwin 266151f0ca8SJohn Baldwin try: 267151f0ca8SJohn Baldwin c = Crypto(crid=crid, 268151f0ca8SJohn Baldwin cipher=cryptodev.CRYPTO_AES_CCM_16, 269151f0ca8SJohn Baldwin key=key, 270151f0ca8SJohn Baldwin mac=cryptodev.CRYPTO_AES_CCM_CBC_MAC, 271151f0ca8SJohn Baldwin mackey=key, maclen=16) 272151f0ca8SJohn Baldwin r, tag = Crypto.encrypt(c, payload, 273151f0ca8SJohn Baldwin nonce, aad) 274b106e0fcSEnji Cooper except EnvironmentError as e: 275151f0ca8SJohn Baldwin if e.errno != errno.EOPNOTSUPP: 276151f0ca8SJohn Baldwin raise 277151f0ca8SJohn Baldwin continue 278151f0ca8SJohn Baldwin 279151f0ca8SJohn Baldwin out = r + tag 280151f0ca8SJohn Baldwin self.assertEqual(out, ct, 281151f0ca8SJohn Baldwin "Count " + data['Count'] + " Actual: " + \ 282e8b4bbdfSEnji Cooper repr(binascii.hexlify(out)) + " Expected: " + \ 283151f0ca8SJohn Baldwin repr(data) + " on " + cname) 284151f0ca8SJohn Baldwin 285151f0ca8SJohn Baldwin def runCCMDecrypt(self, fname): 286a60d9a98SEnji Cooper with cryptodev.KATCCMParser(fname) as parser: 287a60d9a98SEnji Cooper self.runCCMDecryptWithParser(parser) 288a60d9a98SEnji Cooper 289a60d9a98SEnji Cooper def runCCMDecryptWithParser(self, parser): 290151f0ca8SJohn Baldwin # XXX: Note that all of the current CCM 291151f0ca8SJohn Baldwin # decryption test vectors use IV and tag sizes 292151f0ca8SJohn Baldwin # that aren't supported by OCF none of the 293151f0ca8SJohn Baldwin # tests are actually ran. 294a60d9a98SEnji Cooper for data in next(parser): 295151f0ca8SJohn Baldwin Nlen = int(data['Nlen']) 296151f0ca8SJohn Baldwin if Nlen != 12: 297151f0ca8SJohn Baldwin # OCF only supports 12 byte IVs 298151f0ca8SJohn Baldwin continue 299151f0ca8SJohn Baldwin Tlen = int(data['Tlen']) 300151f0ca8SJohn Baldwin if Tlen != 16: 301151f0ca8SJohn Baldwin # OCF only supports 16 byte tags 302151f0ca8SJohn Baldwin continue 303d99c2cecSEnji Cooper key = binascii.unhexlify(data['Key']) 304d99c2cecSEnji Cooper nonce = binascii.unhexlify(data['Nonce']) 305151f0ca8SJohn Baldwin Alen = int(data['Alen']) 306151f0ca8SJohn Baldwin if Alen != 0: 307d99c2cecSEnji Cooper aad = binascii.unhexlify(data['Adata']) 308151f0ca8SJohn Baldwin else: 309151f0ca8SJohn Baldwin aad = None 310d99c2cecSEnji Cooper ct = binascii.unhexlify(data['CT']) 311151f0ca8SJohn Baldwin tag = ct[-16:] 312151f0ca8SJohn Baldwin ct = ct[:-16] 313151f0ca8SJohn Baldwin 314151f0ca8SJohn Baldwin try: 315151f0ca8SJohn Baldwin c = Crypto(crid=crid, 316151f0ca8SJohn Baldwin cipher=cryptodev.CRYPTO_AES_CCM_16, 317151f0ca8SJohn Baldwin key=key, 318151f0ca8SJohn Baldwin mac=cryptodev.CRYPTO_AES_CCM_CBC_MAC, 319151f0ca8SJohn Baldwin mackey=key, maclen=16) 320b106e0fcSEnji Cooper except EnvironmentError as e: 321151f0ca8SJohn Baldwin if e.errno != errno.EOPNOTSUPP: 322151f0ca8SJohn Baldwin raise 323151f0ca8SJohn Baldwin continue 324151f0ca8SJohn Baldwin 325151f0ca8SJohn Baldwin if data['Result'] == 'Fail': 326151f0ca8SJohn Baldwin self.assertRaises(IOError, 327151f0ca8SJohn Baldwin c.decrypt, payload, nonce, aad, tag) 328151f0ca8SJohn Baldwin else: 329151f0ca8SJohn Baldwin r = Crypto.decrypt(c, payload, nonce, 330151f0ca8SJohn Baldwin aad, tag) 331151f0ca8SJohn Baldwin 332d99c2cecSEnji Cooper payload = binascii.unhexlify(data['Payload']) 3332a96ae15SEnji Cooper plen = int(data('Plen')) 334151f0ca8SJohn Baldwin payload = payload[:plen] 335151f0ca8SJohn Baldwin self.assertEqual(r, payload, 336151f0ca8SJohn Baldwin "Count " + data['Count'] + \ 337e8b4bbdfSEnji Cooper " Actual: " + repr(binascii.hexlify(r)) + \ 338151f0ca8SJohn Baldwin " Expected: " + repr(data) + \ 339151f0ca8SJohn Baldwin " on " + cname) 340151f0ca8SJohn Baldwin 34108fca7a5SJohn-Mark Gurney ############### 34208fca7a5SJohn-Mark Gurney ##### DES ##### 34308fca7a5SJohn-Mark Gurney ############### 344d86680b0SEnji Cooper @unittest.skipIf(cname not in desmodules, 'skipping DES on %s' % (cname)) 34508fca7a5SJohn-Mark Gurney def test_tdes(self): 34608fca7a5SJohn-Mark Gurney for i in katg('KAT_TDES', 'TCBC[a-z]*.rsp'): 34708fca7a5SJohn-Mark Gurney self.runTDES(i) 34808fca7a5SJohn-Mark Gurney 34908fca7a5SJohn-Mark Gurney def runTDES(self, fname): 350a60d9a98SEnji Cooper columns = [ 'COUNT', 'KEYs', 'IV', 'PLAINTEXT', 'CIPHERTEXT', ] 351a60d9a98SEnji Cooper with cryptodev.KATParser(fname, columns) as parser: 352a60d9a98SEnji Cooper self.runTDESWithParser(parser) 353a60d9a98SEnji Cooper 354a60d9a98SEnji Cooper def runTDESWithParser(self, parser): 35508fca7a5SJohn-Mark Gurney curfun = None 356a60d9a98SEnji Cooper for mode, lines in next(parser): 35708fca7a5SJohn-Mark Gurney if mode == 'ENCRYPT': 35808fca7a5SJohn-Mark Gurney swapptct = False 35908fca7a5SJohn-Mark Gurney curfun = Crypto.encrypt 36008fca7a5SJohn-Mark Gurney elif mode == 'DECRYPT': 36108fca7a5SJohn-Mark Gurney swapptct = True 36208fca7a5SJohn-Mark Gurney curfun = Crypto.decrypt 36308fca7a5SJohn-Mark Gurney else: 364d86680b0SEnji Cooper raise RuntimeError('unknown mode: %r' % repr(mode)) 36508fca7a5SJohn-Mark Gurney 36608fca7a5SJohn-Mark Gurney for data in lines: 36708fca7a5SJohn-Mark Gurney curcnt = int(data['COUNT']) 36808fca7a5SJohn-Mark Gurney key = data['KEYs'] * 3 369d99c2cecSEnji Cooper cipherkey = binascii.unhexlify(key) 370d99c2cecSEnji Cooper iv = binascii.unhexlify(data['IV']) 371d99c2cecSEnji Cooper pt = binascii.unhexlify(data['PLAINTEXT']) 372d99c2cecSEnji Cooper ct = binascii.unhexlify(data['CIPHERTEXT']) 37308fca7a5SJohn-Mark Gurney 37408fca7a5SJohn-Mark Gurney if swapptct: 37508fca7a5SJohn-Mark Gurney pt, ct = ct, pt 37608fca7a5SJohn-Mark Gurney # run the fun 37708fca7a5SJohn-Mark Gurney c = Crypto(cryptodev.CRYPTO_3DES_CBC, cipherkey, crid=crid) 37808fca7a5SJohn-Mark Gurney r = curfun(c, pt, iv) 37908fca7a5SJohn-Mark Gurney self.assertEqual(r, ct) 38008fca7a5SJohn-Mark Gurney 38108fca7a5SJohn-Mark Gurney ############### 38208fca7a5SJohn-Mark Gurney ##### SHA ##### 38308fca7a5SJohn-Mark Gurney ############### 384d86680b0SEnji Cooper @unittest.skipIf(cname not in shamodules, 'skipping SHA on %s' % str(cname)) 38508fca7a5SJohn-Mark Gurney def test_sha(self): 386de0f7dcaSJohn Baldwin for i in katg('shabytetestvectors', 'SHA*Msg.rsp'): 387de0f7dcaSJohn Baldwin self.runSHA(i) 388de0f7dcaSJohn Baldwin 389de0f7dcaSJohn Baldwin def runSHA(self, fname): 390de0f7dcaSJohn Baldwin # Skip SHA512_(224|256) tests 391de0f7dcaSJohn Baldwin if fname.find('SHA512_') != -1: 392de0f7dcaSJohn Baldwin return 393a60d9a98SEnji Cooper columns = [ 'Len', 'Msg', 'MD' ] 394a60d9a98SEnji Cooper with cryptodev.KATParser(fname, columns) as parser: 395a60d9a98SEnji Cooper self.runSHAWithParser(parser) 396de0f7dcaSJohn Baldwin 397a60d9a98SEnji Cooper def runSHAWithParser(self, parser): 398a60d9a98SEnji Cooper for hashlength, lines in next(parser): 399de0f7dcaSJohn Baldwin # E.g., hashlength will be "L=20" (bytes) 400de0f7dcaSJohn Baldwin hashlen = int(hashlength.split("=")[1]) 401de0f7dcaSJohn Baldwin 402de0f7dcaSJohn Baldwin if hashlen == 20: 403de0f7dcaSJohn Baldwin alg = cryptodev.CRYPTO_SHA1 404de0f7dcaSJohn Baldwin elif hashlen == 28: 405de0f7dcaSJohn Baldwin alg = cryptodev.CRYPTO_SHA2_224 406de0f7dcaSJohn Baldwin elif hashlen == 32: 407de0f7dcaSJohn Baldwin alg = cryptodev.CRYPTO_SHA2_256 408de0f7dcaSJohn Baldwin elif hashlen == 48: 409de0f7dcaSJohn Baldwin alg = cryptodev.CRYPTO_SHA2_384 410de0f7dcaSJohn Baldwin elif hashlen == 64: 411de0f7dcaSJohn Baldwin alg = cryptodev.CRYPTO_SHA2_512 412de0f7dcaSJohn Baldwin else: 413de0f7dcaSJohn Baldwin # Skip unsupported hashes 414de0f7dcaSJohn Baldwin # Slurp remaining input in section 415de0f7dcaSJohn Baldwin for data in lines: 416de0f7dcaSJohn Baldwin continue 417de0f7dcaSJohn Baldwin continue 418de0f7dcaSJohn Baldwin 419de0f7dcaSJohn Baldwin for data in lines: 420d99c2cecSEnji Cooper msg = binascii.unhexlify(data['Msg']) 421de0f7dcaSJohn Baldwin msg = msg[:int(data['Len'])] 422d99c2cecSEnji Cooper md = binascii.unhexlify(data['MD']) 423de0f7dcaSJohn Baldwin 424de0f7dcaSJohn Baldwin try: 425de0f7dcaSJohn Baldwin c = Crypto(mac=alg, crid=crid, 426de0f7dcaSJohn Baldwin maclen=hashlen) 427b106e0fcSEnji Cooper except EnvironmentError as e: 428de0f7dcaSJohn Baldwin # Can't test hashes the driver does not support. 429de0f7dcaSJohn Baldwin if e.errno != errno.EOPNOTSUPP: 430de0f7dcaSJohn Baldwin raise 431de0f7dcaSJohn Baldwin continue 432de0f7dcaSJohn Baldwin 433de0f7dcaSJohn Baldwin _, r = c.encrypt(msg, iv="") 434de0f7dcaSJohn Baldwin 435de0f7dcaSJohn Baldwin self.assertEqual(r, md, "Actual: " + \ 436e8b4bbdfSEnji Cooper repr(binascii.hexlify(r)) + " Expected: " + repr(data) + " on " + cname) 43708fca7a5SJohn-Mark Gurney 438c091d0d9SJohn Baldwin @unittest.skipIf(cname not in shamodules, 'skipping SHA-HMAC on %s' % str(cname)) 43908fca7a5SJohn-Mark Gurney def test_sha1hmac(self): 44008fca7a5SJohn-Mark Gurney for i in katg('hmactestvectors', 'HMAC.rsp'): 44108fca7a5SJohn-Mark Gurney self.runSHA1HMAC(i) 44208fca7a5SJohn-Mark Gurney 44308fca7a5SJohn-Mark Gurney def runSHA1HMAC(self, fname): 444a60d9a98SEnji Cooper columns = [ 'Count', 'Klen', 'Tlen', 'Key', 'Msg', 'Mac' ] 445a60d9a98SEnji Cooper with cryptodev.KATParser(fname, columns) as parser: 446a60d9a98SEnji Cooper self.runSHA1HMACWithParser(parser) 447a60d9a98SEnji Cooper 448a60d9a98SEnji Cooper def runSHA1HMACWithParser(self, parser): 449a60d9a98SEnji Cooper for hashlength, lines in next(parser): 450005fdbbcSConrad Meyer # E.g., hashlength will be "L=20" (bytes) 451005fdbbcSConrad Meyer hashlen = int(hashlength.split("=")[1]) 452005fdbbcSConrad Meyer 453005fdbbcSConrad Meyer blocksize = None 454005fdbbcSConrad Meyer if hashlen == 20: 455005fdbbcSConrad Meyer alg = cryptodev.CRYPTO_SHA1_HMAC 456005fdbbcSConrad Meyer blocksize = 64 457005fdbbcSConrad Meyer elif hashlen == 28: 458c87ada6aSJohn Baldwin alg = cryptodev.CRYPTO_SHA2_224_HMAC 459c87ada6aSJohn Baldwin blocksize = 64 460005fdbbcSConrad Meyer elif hashlen == 32: 461005fdbbcSConrad Meyer alg = cryptodev.CRYPTO_SHA2_256_HMAC 462005fdbbcSConrad Meyer blocksize = 64 463005fdbbcSConrad Meyer elif hashlen == 48: 464005fdbbcSConrad Meyer alg = cryptodev.CRYPTO_SHA2_384_HMAC 465005fdbbcSConrad Meyer blocksize = 128 466005fdbbcSConrad Meyer elif hashlen == 64: 467005fdbbcSConrad Meyer alg = cryptodev.CRYPTO_SHA2_512_HMAC 468005fdbbcSConrad Meyer blocksize = 128 469005fdbbcSConrad Meyer else: 470005fdbbcSConrad Meyer # Skip unsupported hashes 471005fdbbcSConrad Meyer # Slurp remaining input in section 472005fdbbcSConrad Meyer for data in lines: 473005fdbbcSConrad Meyer continue 474005fdbbcSConrad Meyer continue 475005fdbbcSConrad Meyer 47608fca7a5SJohn-Mark Gurney for data in lines: 477d99c2cecSEnji Cooper key = binascii.unhexlify(data['Key']) 478d99c2cecSEnji Cooper msg = binascii.unhexlify(data['Msg']) 479d99c2cecSEnji Cooper mac = binascii.unhexlify(data['Mac']) 480005fdbbcSConrad Meyer tlen = int(data['Tlen']) 48108fca7a5SJohn-Mark Gurney 482005fdbbcSConrad Meyer if len(key) > blocksize: 48308fca7a5SJohn-Mark Gurney continue 48408fca7a5SJohn-Mark Gurney 485a317fb03SConrad Meyer try: 486005fdbbcSConrad Meyer c = Crypto(mac=alg, mackey=key, 487de0f7dcaSJohn Baldwin crid=crid, maclen=hashlen) 488b106e0fcSEnji Cooper except EnvironmentError as e: 489a317fb03SConrad Meyer # Can't test hashes the driver does not support. 490a317fb03SConrad Meyer if e.errno != errno.EOPNOTSUPP: 491a317fb03SConrad Meyer raise 492a317fb03SConrad Meyer continue 49308fca7a5SJohn-Mark Gurney 494005fdbbcSConrad Meyer _, r = c.encrypt(msg, iv="") 495005fdbbcSConrad Meyer 496de0f7dcaSJohn Baldwin self.assertEqual(r[:tlen], mac, "Actual: " + \ 497e8b4bbdfSEnji Cooper repr(binascii.hexlify(r)) + " Expected: " + repr(data)) 49808fca7a5SJohn-Mark Gurney 49908fca7a5SJohn-Mark Gurney return GendCryptoTestCase 50008fca7a5SJohn-Mark Gurney 50108fca7a5SJohn-Mark Gurneycryptosoft = GenTestCase('cryptosoft0') 50208fca7a5SJohn-Mark Gurneyaesni = GenTestCase('aesni0') 503*84a457c6SEnji Cooperarmv8crypto = GenTestCase('armv8crypto0') 5046720b890SJohn Baldwinccr = GenTestCase('ccr0') 505844d9543SConrad Meyerccp = GenTestCase('ccp0') 50608fca7a5SJohn-Mark Gurney 50708fca7a5SJohn-Mark Gurneyif __name__ == '__main__': 50808fca7a5SJohn-Mark Gurney unittest.main() 509