12a7a4b19SAlan Somers#!/usr/local/bin/python3 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# 3108fca7a5SJohn-Mark Gurney 322a7a4b19SAlan Somers 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 52*197ff4c3SKornel Dulebaaesmodules = [ 'cryptosoft0', 'aesni0', 'armv8crypto0', 'ccr0', 'ccp0', 'ossl0', 'safexcel0', 'qat0' ] 53870d4ba3SMark Johnstonshamodules = [ 'cryptosoft0', 'aesni0', 'armv8crypto0', 'ccr0', 'ccp0', 'ossl0', 'safexcel0', 'qat0' ] 5408fca7a5SJohn-Mark Gurney 5508fca7a5SJohn-Mark Gurneydef GenTestCase(cname): 5608fca7a5SJohn-Mark Gurney try: 5708fca7a5SJohn-Mark Gurney crid = cryptodev.Crypto.findcrid(cname) 5808fca7a5SJohn-Mark Gurney except IOError: 5908fca7a5SJohn-Mark Gurney return None 6008fca7a5SJohn-Mark Gurney 6108fca7a5SJohn-Mark Gurney class GendCryptoTestCase(unittest.TestCase): 6208fca7a5SJohn-Mark Gurney ############### 6308fca7a5SJohn-Mark Gurney ##### AES ##### 6408fca7a5SJohn-Mark Gurney ############### 65c091d0d9SJohn Baldwin @unittest.skipIf(cname not in aesmodules, 'skipping AES-XTS on %s' % (cname)) 6608fca7a5SJohn-Mark Gurney def test_xts(self): 6708fca7a5SJohn-Mark Gurney for i in katg('XTSTestVectors/format tweak value input - data unit seq no', '*.rsp'): 6808fca7a5SJohn-Mark Gurney self.runXTS(i, cryptodev.CRYPTO_AES_XTS) 6908fca7a5SJohn-Mark Gurney 70c091d0d9SJohn Baldwin @unittest.skipIf(cname not in aesmodules, 'skipping AES-CBC on %s' % (cname)) 7108fca7a5SJohn-Mark Gurney def test_cbc(self): 7208fca7a5SJohn-Mark Gurney for i in katg('KAT_AES', 'CBC[GKV]*.rsp'): 7308fca7a5SJohn-Mark Gurney self.runCBC(i) 7408fca7a5SJohn-Mark Gurney 75151f0ca8SJohn Baldwin @unittest.skipIf(cname not in aesmodules, 'skipping AES-CCM on %s' % (cname)) 76151f0ca8SJohn Baldwin def test_ccm(self): 77151f0ca8SJohn Baldwin for i in katg('ccmtestvectors', 'V*.rsp'): 78151f0ca8SJohn Baldwin self.runCCMEncrypt(i) 79151f0ca8SJohn Baldwin 80151f0ca8SJohn Baldwin for i in katg('ccmtestvectors', 'D*.rsp'): 81151f0ca8SJohn Baldwin self.runCCMDecrypt(i) 82151f0ca8SJohn Baldwin 83c091d0d9SJohn Baldwin @unittest.skipIf(cname not in aesmodules, 'skipping AES-GCM on %s' % (cname)) 8408fca7a5SJohn-Mark Gurney def test_gcm(self): 8508fca7a5SJohn-Mark Gurney for i in katg('gcmtestvectors', 'gcmEncrypt*'): 8608fca7a5SJohn-Mark Gurney self.runGCM(i, 'ENCRYPT') 8708fca7a5SJohn-Mark Gurney 8808fca7a5SJohn-Mark Gurney for i in katg('gcmtestvectors', 'gcmDecrypt*'): 8908fca7a5SJohn-Mark Gurney self.runGCM(i, 'DECRYPT') 9008fca7a5SJohn-Mark Gurney 9108fca7a5SJohn-Mark Gurney def runGCM(self, fname, mode): 9208fca7a5SJohn-Mark Gurney curfun = None 9308fca7a5SJohn-Mark Gurney if mode == 'ENCRYPT': 9408fca7a5SJohn-Mark Gurney swapptct = False 9508fca7a5SJohn-Mark Gurney curfun = Crypto.encrypt 9608fca7a5SJohn-Mark Gurney elif mode == 'DECRYPT': 9708fca7a5SJohn-Mark Gurney swapptct = True 9808fca7a5SJohn-Mark Gurney curfun = Crypto.decrypt 9908fca7a5SJohn-Mark Gurney else: 100d86680b0SEnji Cooper raise RuntimeError('unknown mode: %r' % repr(mode)) 10108fca7a5SJohn-Mark Gurney 102a60d9a98SEnji Cooper columns = [ 'Count', 'Key', 'IV', 'CT', 'AAD', 'Tag', 'PT', ] 103a60d9a98SEnji Cooper with cryptodev.KATParser(fname, columns) as parser: 104a60d9a98SEnji Cooper self.runGCMWithParser(parser, mode) 105a60d9a98SEnji Cooper 106a60d9a98SEnji Cooper def runGCMWithParser(self, parser, mode): 107a60d9a98SEnji Cooper for _, lines in next(parser): 10808fca7a5SJohn-Mark Gurney for data in lines: 10908fca7a5SJohn-Mark Gurney curcnt = int(data['Count']) 110d99c2cecSEnji Cooper cipherkey = binascii.unhexlify(data['Key']) 111d99c2cecSEnji Cooper iv = binascii.unhexlify(data['IV']) 112d99c2cecSEnji Cooper aad = binascii.unhexlify(data['AAD']) 113d99c2cecSEnji Cooper tag = binascii.unhexlify(data['Tag']) 11408fca7a5SJohn-Mark Gurney if 'FAIL' not in data: 115d99c2cecSEnji Cooper pt = binascii.unhexlify(data['PT']) 116d99c2cecSEnji Cooper ct = binascii.unhexlify(data['CT']) 11708fca7a5SJohn-Mark Gurney 11808fca7a5SJohn-Mark Gurney if len(iv) != 12: 11908fca7a5SJohn-Mark Gurney # XXX - isn't supported 12008fca7a5SJohn-Mark Gurney continue 12108fca7a5SJohn-Mark Gurney 122844d9543SConrad Meyer try: 12308fca7a5SJohn-Mark Gurney c = Crypto(cryptodev.CRYPTO_AES_NIST_GCM_16, 124c0341432SJohn Baldwin cipherkey, crid=crid, 125de0f7dcaSJohn Baldwin maclen=16) 126b106e0fcSEnji Cooper except EnvironmentError as e: 127844d9543SConrad Meyer # Can't test algorithms the driver does not support. 128844d9543SConrad Meyer if e.errno != errno.EOPNOTSUPP: 129844d9543SConrad Meyer raise 130844d9543SConrad Meyer continue 13108fca7a5SJohn-Mark Gurney 13208fca7a5SJohn-Mark Gurney if mode == 'ENCRYPT': 133844d9543SConrad Meyer try: 13408fca7a5SJohn-Mark Gurney rct, rtag = c.encrypt(pt, iv, aad) 135b106e0fcSEnji Cooper except EnvironmentError as e: 136844d9543SConrad Meyer # Can't test inputs the driver does not support. 137844d9543SConrad Meyer if e.errno != errno.EINVAL: 138844d9543SConrad Meyer raise 139844d9543SConrad Meyer continue 14008fca7a5SJohn-Mark Gurney rtag = rtag[:len(tag)] 141d99c2cecSEnji Cooper data['rct'] = binascii.hexlify(rct) 142d99c2cecSEnji Cooper data['rtag'] = binascii.hexlify(rtag) 143d86680b0SEnji Cooper self.assertEqual(rct, ct, repr(data)) 144d86680b0SEnji Cooper self.assertEqual(rtag, tag, repr(data)) 14508fca7a5SJohn-Mark Gurney else: 14608fca7a5SJohn-Mark Gurney if len(tag) != 16: 14708fca7a5SJohn-Mark Gurney continue 14808fca7a5SJohn-Mark Gurney args = (ct, iv, aad, tag) 14908fca7a5SJohn-Mark Gurney if 'FAIL' in data: 15008fca7a5SJohn-Mark Gurney self.assertRaises(IOError, 15108fca7a5SJohn-Mark Gurney c.decrypt, *args) 15208fca7a5SJohn-Mark Gurney else: 153844d9543SConrad Meyer try: 15408fca7a5SJohn-Mark Gurney rpt, rtag = c.decrypt(*args) 155b106e0fcSEnji Cooper except EnvironmentError as e: 156844d9543SConrad Meyer # Can't test inputs the driver does not support. 157844d9543SConrad Meyer if e.errno != errno.EINVAL: 158844d9543SConrad Meyer raise 159844d9543SConrad Meyer continue 160d99c2cecSEnji Cooper data['rpt'] = binascii.hexlify(rpt) 161d99c2cecSEnji Cooper data['rtag'] = binascii.hexlify(rtag) 16208fca7a5SJohn-Mark Gurney self.assertEqual(rpt, pt, 163d86680b0SEnji Cooper repr(data)) 16408fca7a5SJohn-Mark Gurney 16508fca7a5SJohn-Mark Gurney def runCBC(self, fname): 166a60d9a98SEnji Cooper columns = [ 'COUNT', 'KEY', 'IV', 'PLAINTEXT', 'CIPHERTEXT', ] 167a60d9a98SEnji Cooper with cryptodev.KATParser(fname, columns) as parser: 168a60d9a98SEnji Cooper self.runCBCWithParser(parser) 169a60d9a98SEnji Cooper 170a60d9a98SEnji Cooper def runCBCWithParser(self, parser): 17108fca7a5SJohn-Mark Gurney curfun = None 172a60d9a98SEnji Cooper for mode, lines in next(parser): 17308fca7a5SJohn-Mark Gurney if mode == 'ENCRYPT': 17408fca7a5SJohn-Mark Gurney swapptct = False 17508fca7a5SJohn-Mark Gurney curfun = Crypto.encrypt 17608fca7a5SJohn-Mark Gurney elif mode == 'DECRYPT': 17708fca7a5SJohn-Mark Gurney swapptct = True 17808fca7a5SJohn-Mark Gurney curfun = Crypto.decrypt 17908fca7a5SJohn-Mark Gurney else: 180d86680b0SEnji Cooper raise RuntimeError('unknown mode: %r' % repr(mode)) 18108fca7a5SJohn-Mark Gurney 18208fca7a5SJohn-Mark Gurney for data in lines: 18308fca7a5SJohn-Mark Gurney curcnt = int(data['COUNT']) 184d99c2cecSEnji Cooper cipherkey = binascii.unhexlify(data['KEY']) 185d99c2cecSEnji Cooper iv = binascii.unhexlify(data['IV']) 186d99c2cecSEnji Cooper pt = binascii.unhexlify(data['PLAINTEXT']) 187d99c2cecSEnji Cooper ct = binascii.unhexlify(data['CIPHERTEXT']) 18808fca7a5SJohn-Mark Gurney 18908fca7a5SJohn-Mark Gurney if swapptct: 19008fca7a5SJohn-Mark Gurney pt, ct = ct, pt 19108fca7a5SJohn-Mark Gurney # run the fun 19208fca7a5SJohn-Mark Gurney c = Crypto(cryptodev.CRYPTO_AES_CBC, cipherkey, crid=crid) 19308fca7a5SJohn-Mark Gurney r = curfun(c, pt, iv) 19408fca7a5SJohn-Mark Gurney self.assertEqual(r, ct) 19508fca7a5SJohn-Mark Gurney 19608fca7a5SJohn-Mark Gurney def runXTS(self, fname, meth): 197a60d9a98SEnji Cooper columns = [ 'COUNT', 'DataUnitLen', 'Key', 'DataUnitSeqNumber', 'PT', 198a60d9a98SEnji Cooper 'CT'] 199a60d9a98SEnji Cooper with cryptodev.KATParser(fname, columns) as parser: 200a60d9a98SEnji Cooper self.runXTSWithParser(parser, meth) 201a60d9a98SEnji Cooper 202a60d9a98SEnji Cooper def runXTSWithParser(self, parser, meth): 20308fca7a5SJohn-Mark Gurney curfun = None 204a60d9a98SEnji Cooper for mode, lines in next(parser): 20508fca7a5SJohn-Mark Gurney if mode == 'ENCRYPT': 20608fca7a5SJohn-Mark Gurney swapptct = False 20708fca7a5SJohn-Mark Gurney curfun = Crypto.encrypt 20808fca7a5SJohn-Mark Gurney elif mode == 'DECRYPT': 20908fca7a5SJohn-Mark Gurney swapptct = True 21008fca7a5SJohn-Mark Gurney curfun = Crypto.decrypt 21108fca7a5SJohn-Mark Gurney else: 212d86680b0SEnji Cooper raise RuntimeError('unknown mode: %r' % repr(mode)) 21308fca7a5SJohn-Mark Gurney 21408fca7a5SJohn-Mark Gurney for data in lines: 21508fca7a5SJohn-Mark Gurney curcnt = int(data['COUNT']) 21608fca7a5SJohn-Mark Gurney nbits = int(data['DataUnitLen']) 217d99c2cecSEnji Cooper cipherkey = binascii.unhexlify(data['Key']) 21808fca7a5SJohn-Mark Gurney iv = struct.pack('QQ', int(data['DataUnitSeqNumber']), 0) 219d99c2cecSEnji Cooper pt = binascii.unhexlify(data['PT']) 220d99c2cecSEnji Cooper ct = binascii.unhexlify(data['CT']) 22108fca7a5SJohn-Mark Gurney 22208fca7a5SJohn-Mark Gurney if nbits % 128 != 0: 22308fca7a5SJohn-Mark Gurney # XXX - mark as skipped 22408fca7a5SJohn-Mark Gurney continue 22508fca7a5SJohn-Mark Gurney if swapptct: 22608fca7a5SJohn-Mark Gurney pt, ct = ct, pt 22708fca7a5SJohn-Mark Gurney # run the fun 228844d9543SConrad Meyer try: 22908fca7a5SJohn-Mark Gurney c = Crypto(meth, cipherkey, crid=crid) 23008fca7a5SJohn-Mark Gurney r = curfun(c, pt, iv) 231b106e0fcSEnji Cooper except EnvironmentError as e: 232844d9543SConrad Meyer # Can't test hashes the driver does not support. 233844d9543SConrad Meyer if e.errno != errno.EOPNOTSUPP: 234844d9543SConrad Meyer raise 235844d9543SConrad Meyer continue 23608fca7a5SJohn-Mark Gurney self.assertEqual(r, ct) 23708fca7a5SJohn-Mark Gurney 238151f0ca8SJohn Baldwin def runCCMEncrypt(self, fname): 239a60d9a98SEnji Cooper with cryptodev.KATCCMParser(fname) as parser: 240a60d9a98SEnji Cooper self.runCCMEncryptWithParser(parser) 241a60d9a98SEnji Cooper 242a60d9a98SEnji Cooper def runCCMEncryptWithParser(self, parser): 243a60d9a98SEnji Cooper for data in next(parser): 244151f0ca8SJohn Baldwin Nlen = int(data['Nlen']) 245668770dcSJohn Baldwin Tlen = int(data['Tlen']) 246d99c2cecSEnji Cooper key = binascii.unhexlify(data['Key']) 247d99c2cecSEnji Cooper nonce = binascii.unhexlify(data['Nonce']) 248151f0ca8SJohn Baldwin Alen = int(data['Alen']) 249668770dcSJohn Baldwin Plen = int(data['Plen']) 250151f0ca8SJohn Baldwin if Alen != 0: 251d99c2cecSEnji Cooper aad = binascii.unhexlify(data['Adata']) 252151f0ca8SJohn Baldwin else: 253151f0ca8SJohn Baldwin aad = None 254668770dcSJohn Baldwin if Plen != 0: 255d99c2cecSEnji Cooper payload = binascii.unhexlify(data['Payload']) 256668770dcSJohn Baldwin else: 257668770dcSJohn Baldwin payload = None 258d99c2cecSEnji Cooper ct = binascii.unhexlify(data['CT']) 259151f0ca8SJohn Baldwin 260151f0ca8SJohn Baldwin try: 261151f0ca8SJohn Baldwin c = Crypto(crid=crid, 262151f0ca8SJohn Baldwin cipher=cryptodev.CRYPTO_AES_CCM_16, 263151f0ca8SJohn Baldwin key=key, 264668770dcSJohn Baldwin mackey=key, maclen=Tlen, ivlen=Nlen) 265151f0ca8SJohn Baldwin r, tag = Crypto.encrypt(c, payload, 266151f0ca8SJohn Baldwin nonce, aad) 267b106e0fcSEnji Cooper except EnvironmentError as e: 268151f0ca8SJohn Baldwin if e.errno != errno.EOPNOTSUPP: 269151f0ca8SJohn Baldwin raise 270151f0ca8SJohn Baldwin continue 271151f0ca8SJohn Baldwin 272151f0ca8SJohn Baldwin out = r + tag 273151f0ca8SJohn Baldwin self.assertEqual(out, ct, 274151f0ca8SJohn Baldwin "Count " + data['Count'] + " Actual: " + \ 275e8b4bbdfSEnji Cooper repr(binascii.hexlify(out)) + " Expected: " + \ 276151f0ca8SJohn Baldwin repr(data) + " on " + cname) 277151f0ca8SJohn Baldwin 278151f0ca8SJohn Baldwin def runCCMDecrypt(self, fname): 279a60d9a98SEnji Cooper with cryptodev.KATCCMParser(fname) as parser: 280a60d9a98SEnji Cooper self.runCCMDecryptWithParser(parser) 281a60d9a98SEnji Cooper 282a60d9a98SEnji Cooper def runCCMDecryptWithParser(self, parser): 283a60d9a98SEnji Cooper for data in next(parser): 284151f0ca8SJohn Baldwin Nlen = int(data['Nlen']) 285151f0ca8SJohn Baldwin Tlen = int(data['Tlen']) 286d99c2cecSEnji Cooper key = binascii.unhexlify(data['Key']) 287d99c2cecSEnji Cooper nonce = binascii.unhexlify(data['Nonce']) 288151f0ca8SJohn Baldwin Alen = int(data['Alen']) 289668770dcSJohn Baldwin Plen = int(data['Plen']) 290151f0ca8SJohn Baldwin if Alen != 0: 291d99c2cecSEnji Cooper aad = binascii.unhexlify(data['Adata']) 292151f0ca8SJohn Baldwin else: 293151f0ca8SJohn Baldwin aad = None 294d99c2cecSEnji Cooper ct = binascii.unhexlify(data['CT']) 295668770dcSJohn Baldwin tag = ct[-Tlen:] 296668770dcSJohn Baldwin if Plen != 0: 297668770dcSJohn Baldwin payload = ct[:-Tlen] 298668770dcSJohn Baldwin else: 299668770dcSJohn Baldwin payload = None 300151f0ca8SJohn Baldwin 301151f0ca8SJohn Baldwin try: 302151f0ca8SJohn Baldwin c = Crypto(crid=crid, 303151f0ca8SJohn Baldwin cipher=cryptodev.CRYPTO_AES_CCM_16, 304151f0ca8SJohn Baldwin key=key, 305668770dcSJohn Baldwin mackey=key, maclen=Tlen, ivlen=Nlen) 306b106e0fcSEnji Cooper except EnvironmentError as e: 307151f0ca8SJohn Baldwin if e.errno != errno.EOPNOTSUPP: 308151f0ca8SJohn Baldwin raise 309151f0ca8SJohn Baldwin continue 310151f0ca8SJohn Baldwin 311151f0ca8SJohn Baldwin if data['Result'] == 'Fail': 312151f0ca8SJohn Baldwin self.assertRaises(IOError, 313151f0ca8SJohn Baldwin c.decrypt, payload, nonce, aad, tag) 314151f0ca8SJohn Baldwin else: 315668770dcSJohn Baldwin r, tag = Crypto.decrypt(c, payload, nonce, 316151f0ca8SJohn Baldwin aad, tag) 317151f0ca8SJohn Baldwin 318d99c2cecSEnji Cooper payload = binascii.unhexlify(data['Payload']) 319668770dcSJohn Baldwin payload = payload[:Plen] 320151f0ca8SJohn Baldwin self.assertEqual(r, payload, 321151f0ca8SJohn Baldwin "Count " + data['Count'] + \ 322e8b4bbdfSEnji Cooper " Actual: " + repr(binascii.hexlify(r)) + \ 323151f0ca8SJohn Baldwin " Expected: " + repr(data) + \ 324151f0ca8SJohn Baldwin " on " + cname) 325151f0ca8SJohn Baldwin 32608fca7a5SJohn-Mark Gurney ############### 32708fca7a5SJohn-Mark Gurney ##### SHA ##### 32808fca7a5SJohn-Mark Gurney ############### 329d86680b0SEnji Cooper @unittest.skipIf(cname not in shamodules, 'skipping SHA on %s' % str(cname)) 33008fca7a5SJohn-Mark Gurney def test_sha(self): 331de0f7dcaSJohn Baldwin for i in katg('shabytetestvectors', 'SHA*Msg.rsp'): 332de0f7dcaSJohn Baldwin self.runSHA(i) 333de0f7dcaSJohn Baldwin 334de0f7dcaSJohn Baldwin def runSHA(self, fname): 335de0f7dcaSJohn Baldwin # Skip SHA512_(224|256) tests 336de0f7dcaSJohn Baldwin if fname.find('SHA512_') != -1: 337de0f7dcaSJohn Baldwin return 338a60d9a98SEnji Cooper columns = [ 'Len', 'Msg', 'MD' ] 339a60d9a98SEnji Cooper with cryptodev.KATParser(fname, columns) as parser: 340a60d9a98SEnji Cooper self.runSHAWithParser(parser) 341de0f7dcaSJohn Baldwin 342a60d9a98SEnji Cooper def runSHAWithParser(self, parser): 343a60d9a98SEnji Cooper for hashlength, lines in next(parser): 344de0f7dcaSJohn Baldwin # E.g., hashlength will be "L=20" (bytes) 345de0f7dcaSJohn Baldwin hashlen = int(hashlength.split("=")[1]) 346de0f7dcaSJohn Baldwin 347de0f7dcaSJohn Baldwin if hashlen == 20: 348de0f7dcaSJohn Baldwin alg = cryptodev.CRYPTO_SHA1 349de0f7dcaSJohn Baldwin elif hashlen == 28: 350de0f7dcaSJohn Baldwin alg = cryptodev.CRYPTO_SHA2_224 351de0f7dcaSJohn Baldwin elif hashlen == 32: 352de0f7dcaSJohn Baldwin alg = cryptodev.CRYPTO_SHA2_256 353de0f7dcaSJohn Baldwin elif hashlen == 48: 354de0f7dcaSJohn Baldwin alg = cryptodev.CRYPTO_SHA2_384 355de0f7dcaSJohn Baldwin elif hashlen == 64: 356de0f7dcaSJohn Baldwin alg = cryptodev.CRYPTO_SHA2_512 357de0f7dcaSJohn Baldwin else: 358de0f7dcaSJohn Baldwin # Skip unsupported hashes 359de0f7dcaSJohn Baldwin # Slurp remaining input in section 360de0f7dcaSJohn Baldwin for data in lines: 361de0f7dcaSJohn Baldwin continue 362de0f7dcaSJohn Baldwin continue 363de0f7dcaSJohn Baldwin 364de0f7dcaSJohn Baldwin for data in lines: 365d99c2cecSEnji Cooper msg = binascii.unhexlify(data['Msg']) 366de0f7dcaSJohn Baldwin msg = msg[:int(data['Len'])] 367d99c2cecSEnji Cooper md = binascii.unhexlify(data['MD']) 368de0f7dcaSJohn Baldwin 369de0f7dcaSJohn Baldwin try: 370de0f7dcaSJohn Baldwin c = Crypto(mac=alg, crid=crid, 371de0f7dcaSJohn Baldwin maclen=hashlen) 372b106e0fcSEnji Cooper except EnvironmentError as e: 373de0f7dcaSJohn Baldwin # Can't test hashes the driver does not support. 374de0f7dcaSJohn Baldwin if e.errno != errno.EOPNOTSUPP: 375de0f7dcaSJohn Baldwin raise 376de0f7dcaSJohn Baldwin continue 377de0f7dcaSJohn Baldwin 378de0f7dcaSJohn Baldwin _, r = c.encrypt(msg, iv="") 379de0f7dcaSJohn Baldwin 380de0f7dcaSJohn Baldwin self.assertEqual(r, md, "Actual: " + \ 381e8b4bbdfSEnji Cooper repr(binascii.hexlify(r)) + " Expected: " + repr(data) + " on " + cname) 38208fca7a5SJohn-Mark Gurney 383c091d0d9SJohn Baldwin @unittest.skipIf(cname not in shamodules, 'skipping SHA-HMAC on %s' % str(cname)) 38408fca7a5SJohn-Mark Gurney def test_sha1hmac(self): 38508fca7a5SJohn-Mark Gurney for i in katg('hmactestvectors', 'HMAC.rsp'): 38608fca7a5SJohn-Mark Gurney self.runSHA1HMAC(i) 38708fca7a5SJohn-Mark Gurney 38808fca7a5SJohn-Mark Gurney def runSHA1HMAC(self, fname): 389a60d9a98SEnji Cooper columns = [ 'Count', 'Klen', 'Tlen', 'Key', 'Msg', 'Mac' ] 390a60d9a98SEnji Cooper with cryptodev.KATParser(fname, columns) as parser: 391a60d9a98SEnji Cooper self.runSHA1HMACWithParser(parser) 392a60d9a98SEnji Cooper 393a60d9a98SEnji Cooper def runSHA1HMACWithParser(self, parser): 394a60d9a98SEnji Cooper for hashlength, lines in next(parser): 395005fdbbcSConrad Meyer # E.g., hashlength will be "L=20" (bytes) 396005fdbbcSConrad Meyer hashlen = int(hashlength.split("=")[1]) 397005fdbbcSConrad Meyer 398005fdbbcSConrad Meyer blocksize = None 399005fdbbcSConrad Meyer if hashlen == 20: 400005fdbbcSConrad Meyer alg = cryptodev.CRYPTO_SHA1_HMAC 401005fdbbcSConrad Meyer blocksize = 64 402005fdbbcSConrad Meyer elif hashlen == 28: 403c87ada6aSJohn Baldwin alg = cryptodev.CRYPTO_SHA2_224_HMAC 404c87ada6aSJohn Baldwin blocksize = 64 405005fdbbcSConrad Meyer elif hashlen == 32: 406005fdbbcSConrad Meyer alg = cryptodev.CRYPTO_SHA2_256_HMAC 407005fdbbcSConrad Meyer blocksize = 64 408005fdbbcSConrad Meyer elif hashlen == 48: 409005fdbbcSConrad Meyer alg = cryptodev.CRYPTO_SHA2_384_HMAC 410005fdbbcSConrad Meyer blocksize = 128 411005fdbbcSConrad Meyer elif hashlen == 64: 412005fdbbcSConrad Meyer alg = cryptodev.CRYPTO_SHA2_512_HMAC 413005fdbbcSConrad Meyer blocksize = 128 414005fdbbcSConrad Meyer else: 415005fdbbcSConrad Meyer # Skip unsupported hashes 416005fdbbcSConrad Meyer # Slurp remaining input in section 417005fdbbcSConrad Meyer for data in lines: 418005fdbbcSConrad Meyer continue 419005fdbbcSConrad Meyer continue 420005fdbbcSConrad Meyer 42108fca7a5SJohn-Mark Gurney for data in lines: 422d99c2cecSEnji Cooper key = binascii.unhexlify(data['Key']) 423d99c2cecSEnji Cooper msg = binascii.unhexlify(data['Msg']) 424d99c2cecSEnji Cooper mac = binascii.unhexlify(data['Mac']) 425005fdbbcSConrad Meyer tlen = int(data['Tlen']) 42608fca7a5SJohn-Mark Gurney 427005fdbbcSConrad Meyer if len(key) > blocksize: 42808fca7a5SJohn-Mark Gurney continue 42908fca7a5SJohn-Mark Gurney 430a317fb03SConrad Meyer try: 431005fdbbcSConrad Meyer c = Crypto(mac=alg, mackey=key, 432de0f7dcaSJohn Baldwin crid=crid, maclen=hashlen) 433b106e0fcSEnji Cooper except EnvironmentError as e: 434a317fb03SConrad Meyer # Can't test hashes the driver does not support. 435a317fb03SConrad Meyer if e.errno != errno.EOPNOTSUPP: 436a317fb03SConrad Meyer raise 437a317fb03SConrad Meyer continue 43808fca7a5SJohn-Mark Gurney 439005fdbbcSConrad Meyer _, r = c.encrypt(msg, iv="") 440005fdbbcSConrad Meyer 441de0f7dcaSJohn Baldwin self.assertEqual(r[:tlen], mac, "Actual: " + \ 442e8b4bbdfSEnji Cooper repr(binascii.hexlify(r)) + " Expected: " + repr(data)) 44308fca7a5SJohn-Mark Gurney 44408fca7a5SJohn-Mark Gurney return GendCryptoTestCase 44508fca7a5SJohn-Mark Gurney 44608fca7a5SJohn-Mark Gurneycryptosoft = GenTestCase('cryptosoft0') 44708fca7a5SJohn-Mark Gurneyaesni = GenTestCase('aesni0') 44884a457c6SEnji Cooperarmv8crypto = GenTestCase('armv8crypto0') 4496720b890SJohn Baldwinccr = GenTestCase('ccr0') 450844d9543SConrad Meyerccp = GenTestCase('ccp0') 451ac619349SJung-uk Kimossl = GenTestCase('ossl0') 4529a1184deSMark Johnstonsafexcel = GenTestCase('safexcel0') 453870d4ba3SMark Johnstonqat = GenTestCase('qat0') 45408fca7a5SJohn-Mark Gurney 45508fca7a5SJohn-Mark Gurneyif __name__ == '__main__': 45608fca7a5SJohn-Mark Gurney unittest.main() 457