1#!/usr/local/bin/python2 2# 3# Copyright (c) 2014 The FreeBSD Foundation 4# Copyright 2014 John-Mark Gurney 5# All rights reserved. 6# 7# This software was developed by John-Mark Gurney under 8# the sponsorship from the FreeBSD Foundation. 9# Redistribution and use in source and binary forms, with or without 10# modification, are permitted provided that the following conditions 11# are met: 12# 1. Redistributions of source code must retain the above copyright 13# notice, this list of conditions and the following disclaimer. 14# 2. Redistributions in binary form must reproduce the above copyright 15# notice, this list of conditions and the following disclaimer in the 16# documentation and/or other materials provided with the distribution. 17# 18# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28# SUCH DAMAGE. 29# 30# $FreeBSD$ 31# 32 33from __future__ import print_function 34import array 35import dpkt 36from fcntl import ioctl 37import os 38import random 39import signal 40from struct import pack as _pack 41import time 42 43from cryptodevh import * 44 45__all__ = [ 'Crypto', 'MismatchError', ] 46 47class FindOp(dpkt.Packet): 48 __byte_order__ = '@' 49 __hdr__ = ( 50 ('crid', 'i', 0), 51 ('name', '32s', 0), 52 ) 53 54class SessionOp(dpkt.Packet): 55 __byte_order__ = '@' 56 __hdr__ = ( 57 ('cipher', 'I', 0), 58 ('mac', 'I', 0), 59 ('keylen', 'I', 0), 60 ('key', 'P', 0), 61 ('mackeylen', 'i', 0), 62 ('mackey', 'P', 0), 63 ('ses', 'I', 0), 64 ) 65 66class SessionOp2(dpkt.Packet): 67 __byte_order__ = '@' 68 __hdr__ = ( 69 ('cipher', 'I', 0), 70 ('mac', 'I', 0), 71 ('keylen', 'I', 0), 72 ('key', 'P', 0), 73 ('mackeylen', 'i', 0), 74 ('mackey', 'P', 0), 75 ('ses', 'I', 0), 76 ('crid', 'i', 0), 77 ('pad0', 'i', 0), 78 ('pad1', 'i', 0), 79 ('pad2', 'i', 0), 80 ('pad3', 'i', 0), 81 ) 82 83class CryptOp(dpkt.Packet): 84 __byte_order__ = '@' 85 __hdr__ = ( 86 ('ses', 'I', 0), 87 ('op', 'H', 0), 88 ('flags', 'H', 0), 89 ('len', 'I', 0), 90 ('src', 'P', 0), 91 ('dst', 'P', 0), 92 ('mac', 'P', 0), 93 ('iv', 'P', 0), 94 ) 95 96class CryptAEAD(dpkt.Packet): 97 __byte_order__ = '@' 98 __hdr__ = ( 99 ('ses', 'I', 0), 100 ('op', 'H', 0), 101 ('flags', 'H', 0), 102 ('len', 'I', 0), 103 ('aadlen', 'I', 0), 104 ('ivlen', 'I', 0), 105 ('src', 'P', 0), 106 ('dst', 'P', 0), 107 ('aad', 'P', 0), 108 ('tag', 'P', 0), 109 ('iv', 'P', 0), 110 ) 111 112# h2py.py can't handle multiarg macros 113CRIOGET = 3221513060 114CIOCGSESSION = 3224396645 115CIOCGSESSION2 = 3225445226 116CIOCFSESSION = 2147771238 117CIOCCRYPT = 3224396647 118CIOCKEY = 3230688104 119CIOCASYMFEAT = 1074029417 120CIOCKEY2 = 3230688107 121CIOCFINDDEV = 3223610220 122CIOCCRYPTAEAD = 3225445229 123 124def _getdev(): 125 buf = array.array('I', [0]) 126 fd = os.open('/dev/crypto', os.O_RDWR) 127 try: 128 ioctl(fd, CRIOGET, buf, 1) 129 finally: 130 os.close(fd) 131 132 return buf[0] 133 134_cryptodev = _getdev() 135 136def _findop(crid, name): 137 fop = FindOp() 138 fop.crid = crid 139 fop.name = name 140 s = array.array('B', fop.pack_hdr()) 141 ioctl(_cryptodev, CIOCFINDDEV, s, 1) 142 fop.unpack(s) 143 144 try: 145 idx = fop.name.index('\x00') 146 name = fop.name[:idx] 147 except ValueError: 148 name = fop.name 149 150 return fop.crid, name 151 152class Crypto: 153 @staticmethod 154 def findcrid(name): 155 return _findop(-1, name)[0] 156 157 @staticmethod 158 def getcridname(crid): 159 return _findop(crid, '')[1] 160 161 def __init__(self, cipher=0, key=None, mac=0, mackey=None, 162 crid=CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE, maclen=None): 163 self._ses = None 164 self._maclen = maclen 165 ses = SessionOp2() 166 ses.cipher = cipher 167 ses.mac = mac 168 169 if key is not None: 170 ses.keylen = len(key) 171 k = array.array('B', key) 172 ses.key = k.buffer_info()[0] 173 else: 174 self.key = None 175 176 if mackey is not None: 177 ses.mackeylen = len(mackey) 178 mk = array.array('B', mackey) 179 ses.mackey = mk.buffer_info()[0] 180 181 if not cipher and not mac: 182 raise ValueError('one of cipher or mac MUST be specified.') 183 ses.crid = crid 184 #print(ses) 185 s = array.array('B', ses.pack_hdr()) 186 #print(s) 187 ioctl(_cryptodev, CIOCGSESSION2, s, 1) 188 ses.unpack(s) 189 190 self._ses = ses.ses 191 192 def __del__(self): 193 if self._ses is None: 194 return 195 196 try: 197 ioctl(_cryptodev, CIOCFSESSION, _pack('I', self._ses)) 198 except TypeError: 199 pass 200 self._ses = None 201 202 def _doop(self, op, src, iv): 203 cop = CryptOp() 204 cop.ses = self._ses 205 cop.op = op 206 cop.flags = 0 207 cop.len = len(src) 208 s = array.array('B', src) 209 cop.src = cop.dst = s.buffer_info()[0] 210 if self._maclen is not None: 211 m = array.array('B', [0] * self._maclen) 212 cop.mac = m.buffer_info()[0] 213 ivbuf = array.array('B', iv) 214 cop.iv = ivbuf.buffer_info()[0] 215 216 #print('cop:', cop) 217 ioctl(_cryptodev, CIOCCRYPT, str(cop)) 218 219 s = s.tostring() 220 if self._maclen is not None: 221 return s, m.tostring() 222 223 return s 224 225 def _doaead(self, op, src, aad, iv, tag=None): 226 caead = CryptAEAD() 227 caead.ses = self._ses 228 caead.op = op 229 caead.flags = CRD_F_IV_EXPLICIT 230 caead.flags = 0 231 caead.len = len(src) 232 s = array.array('B', src) 233 caead.src = caead.dst = s.buffer_info()[0] 234 caead.aadlen = len(aad) 235 saad = array.array('B', aad) 236 caead.aad = saad.buffer_info()[0] 237 238 if self._maclen is None: 239 raise ValueError('must have a tag length') 240 241 if tag is None: 242 tag = array.array('B', [0] * self._maclen) 243 else: 244 assert len(tag) == self._maclen, \ 245 '%d != %d' % (len(tag), self._maclen) 246 tag = array.array('B', tag) 247 248 caead.tag = tag.buffer_info()[0] 249 250 ivbuf = array.array('B', iv) 251 caead.ivlen = len(iv) 252 caead.iv = ivbuf.buffer_info()[0] 253 254 ioctl(_cryptodev, CIOCCRYPTAEAD, str(caead)) 255 256 s = s.tostring() 257 258 return s, tag.tostring() 259 260 def perftest(self, op, size, timeo=3): 261 inp = array.array('B', (random.randint(0, 255) for x in range(size))) 262 out = array.array('B', inp) 263 264 # prep ioctl 265 cop = CryptOp() 266 cop.ses = self._ses 267 cop.op = op 268 cop.flags = 0 269 cop.len = len(inp) 270 s = array.array('B', inp) 271 cop.src = s.buffer_info()[0] 272 cop.dst = out.buffer_info()[0] 273 if self._maclen is not None: 274 m = array.array('B', [0] * self._maclen) 275 cop.mac = m.buffer_info()[0] 276 ivbuf = array.array('B', (random.randint(0, 255) for x in range(16))) 277 cop.iv = ivbuf.buffer_info()[0] 278 279 exit = [ False ] 280 def alarmhandle(a, b, exit=exit): 281 exit[0] = True 282 283 oldalarm = signal.signal(signal.SIGALRM, alarmhandle) 284 signal.alarm(timeo) 285 286 start = time.time() 287 reps = 0 288 while not exit[0]: 289 ioctl(_cryptodev, CIOCCRYPT, str(cop)) 290 reps += 1 291 292 end = time.time() 293 294 signal.signal(signal.SIGALRM, oldalarm) 295 296 print('time:', end - start) 297 print('perf MB/sec:', (reps * size) / (end - start) / 1024 / 1024) 298 299 def encrypt(self, data, iv, aad=None): 300 if aad is None: 301 return self._doop(COP_ENCRYPT, data, iv) 302 else: 303 return self._doaead(COP_ENCRYPT, data, aad, 304 iv) 305 306 def decrypt(self, data, iv, aad=None, tag=None): 307 if aad is None: 308 return self._doop(COP_DECRYPT, data, iv) 309 else: 310 return self._doaead(COP_DECRYPT, data, aad, 311 iv, tag=tag) 312 313class MismatchError(Exception): 314 pass 315 316class KATParser: 317 def __init__(self, fname, fields): 318 self.fp = open(fname) 319 self.fields = set(fields) 320 self._pending = None 321 322 def __iter__(self): 323 while True: 324 didread = False 325 if self._pending is not None: 326 i = self._pending 327 self._pending = None 328 else: 329 i = self.fp.readline() 330 didread = True 331 332 if didread and not i: 333 return 334 335 if (i and i[0] == '#') or not i.strip(): 336 continue 337 if i[0] == '[': 338 yield i[1:].split(']', 1)[0], self.fielditer() 339 else: 340 raise ValueError('unknown line: %r' % repr(i)) 341 342 def eatblanks(self): 343 while True: 344 line = self.fp.readline() 345 if line == '': 346 break 347 348 line = line.strip() 349 if line: 350 break 351 352 return line 353 354 def fielditer(self): 355 while True: 356 values = {} 357 358 line = self.eatblanks() 359 if not line or line[0] == '[': 360 self._pending = line 361 return 362 363 while True: 364 try: 365 f, v = line.split(' =') 366 except: 367 if line == 'FAIL': 368 f, v = 'FAIL', '' 369 else: 370 print('line:', repr(line)) 371 raise 372 v = v.strip() 373 374 if f in values: 375 raise ValueError('already present: %r' % repr(f)) 376 values[f] = v 377 line = self.fp.readline().strip() 378 if not line: 379 break 380 381 # we should have everything 382 remain = self.fields.copy() - set(values.keys()) 383 # XXX - special case GCM decrypt 384 if remain and not ('FAIL' in values and 'PT' in remain): 385 raise ValueError('not all fields found: %r' % repr(remain)) 386 387 yield values 388 389# The CCM files use a bit of a different syntax that doesn't quite fit 390# the generic KATParser. In particular, some keys are set globally at 391# the start of the file, and some are set globally at the start of a 392# section. 393class KATCCMParser: 394 def __init__(self, fname): 395 self.fp = open(fname) 396 self._pending = None 397 self.read_globals() 398 399 def read_globals(self): 400 self.global_values = {} 401 while True: 402 line = self.fp.readline() 403 if not line: 404 return 405 if line[0] == '#' or not line.strip(): 406 continue 407 if line[0] == '[': 408 self._pending = line 409 return 410 411 try: 412 f, v = line.split(' =') 413 except: 414 print('line:', repr(line)) 415 raise 416 417 v = v.strip() 418 419 if f in self.global_values: 420 raise ValueError('already present: %r' % repr(f)) 421 self.global_values[f] = v 422 423 def read_section_values(self, kwpairs): 424 self.section_values = self.global_values.copy() 425 for pair in kwpairs.split(', '): 426 f, v = pair.split(' = ') 427 if f in self.section_values: 428 raise ValueError('already present: %r' % repr(f)) 429 self.section_values[f] = v 430 431 while True: 432 line = self.fp.readline() 433 if not line: 434 return 435 if line[0] == '#' or not line.strip(): 436 continue 437 if line[0] == '[': 438 self._pending = line 439 return 440 441 try: 442 f, v = line.split(' =') 443 except: 444 print('line:', repr(line)) 445 raise 446 447 if f == 'Count': 448 self._pending = line 449 return 450 451 v = v.strip() 452 453 if f in self.section_values: 454 raise ValueError('already present: %r' % repr(f)) 455 self.section_values[f] = v 456 457 def __iter__(self): 458 while True: 459 if self._pending: 460 line = self._pending 461 self._pending = None 462 else: 463 line = self.fp.readline() 464 if not line: 465 return 466 467 if (line and line[0] == '#') or not line.strip(): 468 continue 469 470 if line[0] == '[': 471 section = line[1:].split(']', 1)[0] 472 self.read_section_values(section) 473 continue 474 475 values = self.section_values.copy() 476 477 while True: 478 try: 479 f, v = line.split(' =') 480 except: 481 print('line:', repr(line)) 482 raise 483 v = v.strip() 484 485 if f in values: 486 raise ValueError('already present: %r' % repr(f)) 487 values[f] = v 488 line = self.fp.readline().strip() 489 if not line: 490 break 491 492 yield values 493 494 495def _spdechex(s): 496 return ''.join(s.split()).decode('hex') 497 498if __name__ == '__main__': 499 if True: 500 try: 501 crid = Crypto.findcrid('aesni0') 502 print('aesni:', crid) 503 except IOError: 504 print('aesni0 not found') 505 506 for i in range(10): 507 try: 508 name = Crypto.getcridname(i) 509 print('%2d: %r' % (i, repr(name))) 510 except IOError: 511 pass 512 elif False: 513 kp = KATParser('/usr/home/jmg/aesni.testing/format tweak value input - data unit seq no/XTSGenAES128.rsp', [ 'COUNT', 'DataUnitLen', 'Key', 'DataUnitSeqNumber', 'PT', 'CT' ]) 514 for mode, ni in kp: 515 print(i, ni) 516 for j in ni: 517 print(j) 518 elif False: 519 key = _spdechex('c939cc13397c1d37de6ae0e1cb7c423c') 520 iv = _spdechex('00000000000000000000000000000001') 521 pt = _spdechex('ab3cabed693a32946055524052afe3c9cb49664f09fc8b7da824d924006b7496353b8c1657c5dec564d8f38d7432e1de35aae9d95590e66278d4acce883e51abaf94977fcd3679660109a92bf7b2973ccd547f065ec6cee4cb4a72a5e9f45e615d920d76cb34cba482467b3e21422a7242e7d931330c0fbf465c3a3a46fae943029fd899626dda542750a1eee253df323c6ef1573f1c8c156613e2ea0a6cdbf2ae9701020be2d6a83ecb7f3f9d8e') 522 #pt = _spdechex('00000000000000000000000000000000') 523 ct = _spdechex('f42c33853ecc5ce2949865fdb83de3bff1089e9360c94f830baebfaff72836ab5236f77212f1e7396c8c54ac73d81986375a6e9e299cfeca5ba051ed25e8d1affa5beaf6c1d2b45e90802408f2ced21663497e906de5f29341e5e52ddfea5363d628b3eb7806835e17bae051b3a6da3f8e2941fe44384eac17a9d298d2c331ca8320c775b5d53263a5e905059d891b21dede2d8110fd427c7bd5a9a274ddb47b1945ee79522203b6e297d0e399ef') 524 525 c = Crypto(CRYPTO_AES_ICM, key) 526 enc = c.encrypt(pt, iv) 527 528 print('enc:', enc.encode('hex')) 529 print(' ct:', ct.encode('hex')) 530 531 assert ct == enc 532 533 dec = c.decrypt(ct, iv) 534 535 print('dec:', dec.encode('hex')) 536 print(' pt:', pt.encode('hex')) 537 538 assert pt == dec 539 elif False: 540 key = _spdechex('c939cc13397c1d37de6ae0e1cb7c423c') 541 iv = _spdechex('00000000000000000000000000000001') 542 pt = _spdechex('ab3cabed693a32946055524052afe3c9cb49664f09fc8b7da824d924006b7496353b8c1657c5dec564d8f38d7432e1de35aae9d95590e66278d4acce883e51abaf94977fcd3679660109a92bf7b2973ccd547f065ec6cee4cb4a72a5e9f45e615d920d76cb34cba482467b3e21422a7242e7d931330c0fbf465c3a3a46fae943029fd899626dda542750a1eee253df323c6ef1573f1c8c156613e2ea0a6cdbf2ae9701020be2d6a83ecb7f3f9d8e0a3f') 543 #pt = _spdechex('00000000000000000000000000000000') 544 ct = _spdechex('f42c33853ecc5ce2949865fdb83de3bff1089e9360c94f830baebfaff72836ab5236f77212f1e7396c8c54ac73d81986375a6e9e299cfeca5ba051ed25e8d1affa5beaf6c1d2b45e90802408f2ced21663497e906de5f29341e5e52ddfea5363d628b3eb7806835e17bae051b3a6da3f8e2941fe44384eac17a9d298d2c331ca8320c775b5d53263a5e905059d891b21dede2d8110fd427c7bd5a9a274ddb47b1945ee79522203b6e297d0e399ef3768') 545 546 c = Crypto(CRYPTO_AES_ICM, key) 547 enc = c.encrypt(pt, iv) 548 549 print('enc:', enc.encode('hex')) 550 print(' ct:', ct.encode('hex')) 551 552 assert ct == enc 553 554 dec = c.decrypt(ct, iv) 555 556 print('dec:', dec.encode('hex')) 557 print(' pt:', pt.encode('hex')) 558 559 assert pt == dec 560 elif False: 561 key = _spdechex('c939cc13397c1d37de6ae0e1cb7c423c') 562 iv = _spdechex('6eba2716ec0bd6fa5cdef5e6d3a795bc') 563 pt = _spdechex('ab3cabed693a32946055524052afe3c9cb49664f09fc8b7da824d924006b7496353b8c1657c5dec564d8f38d7432e1de35aae9d95590e66278d4acce883e51abaf94977fcd3679660109a92bf7b2973ccd547f065ec6cee4cb4a72a5e9f45e615d920d76cb34cba482467b3e21422a7242e7d931330c0fbf465c3a3a46fae943029fd899626dda542750a1eee253df323c6ef1573f1c8c156613e2ea0a6cdbf2ae9701020be2d6a83ecb7f3f9d8e0a3f') 564 ct = _spdechex('f1f81f12e72e992dbdc304032705dc75dc3e4180eff8ee4819906af6aee876d5b00b7c36d282a445ce3620327be481e8e53a8e5a8e5ca9abfeb2281be88d12ffa8f46d958d8224738c1f7eea48bda03edbf9adeb900985f4fa25648b406d13a886c25e70cfdecdde0ad0f2991420eb48a61c64fd797237cf2798c2675b9bb744360b0a3f329ac53bbceb4e3e7456e6514f1a9d2f06c236c31d0f080b79c15dce1096357416602520daa098b17d1af427') 565 c = Crypto(CRYPTO_AES_CBC, key) 566 567 enc = c.encrypt(pt, iv) 568 569 print('enc:', enc.encode('hex')) 570 print(' ct:', ct.encode('hex')) 571 572 assert ct == enc 573 574 dec = c.decrypt(ct, iv) 575 576 print('dec:', dec.encode('hex')) 577 print(' pt:', pt.encode('hex')) 578 579 assert pt == dec 580 elif False: 581 key = _spdechex('c939cc13397c1d37de6ae0e1cb7c423c') 582 iv = _spdechex('b3d8cc017cbb89b39e0f67e2') 583 pt = _spdechex('c3b3c41f113a31b73d9a5cd4321030') 584 aad = _spdechex('24825602bd12a984e0092d3e448eda5f') 585 ct = _spdechex('93fe7d9e9bfd10348a5606e5cafa7354') 586 ct = _spdechex('93fe7d9e9bfd10348a5606e5cafa73') 587 tag = _spdechex('0032a1dc85f1c9786925a2e71d8272dd') 588 tag = _spdechex('8d11a0929cb3fbe1fef01a4a38d5f8ea') 589 590 c = Crypto(CRYPTO_AES_NIST_GCM_16, key, 591 mac=CRYPTO_AES_128_NIST_GMAC, mackey=key) 592 593 enc, enctag = c.encrypt(pt, iv, aad=aad) 594 595 print('enc:', enc.encode('hex')) 596 print(' ct:', ct.encode('hex')) 597 598 assert enc == ct 599 600 print('etg:', enctag.encode('hex')) 601 print('tag:', tag.encode('hex')) 602 assert enctag == tag 603 604 # Make sure we get EBADMSG 605 #enctag = enctag[:-1] + 'a' 606 dec, dectag = c.decrypt(ct, iv, aad=aad, tag=enctag) 607 608 print('dec:', dec.encode('hex')) 609 print(' pt:', pt.encode('hex')) 610 611 assert dec == pt 612 613 print('dtg:', dectag.encode('hex')) 614 print('tag:', tag.encode('hex')) 615 616 assert dectag == tag 617 elif False: 618 key = _spdechex('c939cc13397c1d37de6ae0e1cb7c423c') 619 iv = _spdechex('b3d8cc017cbb89b39e0f67e2') 620 key = key + iv[:4] 621 iv = iv[4:] 622 pt = _spdechex('c3b3c41f113a31b73d9a5cd432103069') 623 aad = _spdechex('24825602bd12a984e0092d3e448eda5f') 624 ct = _spdechex('93fe7d9e9bfd10348a5606e5cafa7354') 625 tag = _spdechex('0032a1dc85f1c9786925a2e71d8272dd') 626 627 c = Crypto(CRYPTO_AES_GCM_16, key, mac=CRYPTO_AES_128_GMAC, mackey=key) 628 629 enc, enctag = c.encrypt(pt, iv, aad=aad) 630 631 print('enc:', enc.encode('hex')) 632 print(' ct:', ct.encode('hex')) 633 634 assert enc == ct 635 636 print('etg:', enctag.encode('hex')) 637 print('tag:', tag.encode('hex')) 638 assert enctag == tag 639 elif False: 640 for i in range(100000): 641 c = Crypto(CRYPTO_AES_XTS, '1bbfeadf539daedcae33ced497343f3ca1f2474ad932b903997d44707db41382'.decode('hex')) 642 data = '52a42bca4e9425a25bbc8c8bf6129dec'.decode('hex') 643 ct = '517e602becd066b65fa4f4f56ddfe240'.decode('hex') 644 iv = _pack('QQ', 71, 0) 645 646 enc = c.encrypt(data, iv) 647 assert enc == ct 648 elif True: 649 c = Crypto(CRYPTO_AES_XTS, '1bbfeadf539daedcae33ced497343f3ca1f2474ad932b903997d44707db41382'.decode('hex')) 650 data = '52a42bca4e9425a25bbc8c8bf6129dec'.decode('hex') 651 ct = '517e602becd066b65fa4f4f56ddfe240'.decode('hex') 652 iv = _pack('QQ', 71, 0) 653 654 enc = c.encrypt(data, iv) 655 assert enc == ct 656 657 dec = c.decrypt(enc, iv) 658 assert dec == data 659 660 #c.perftest(COP_ENCRYPT, 192*1024, reps=30000) 661 662 else: 663 key = '1bbfeadf539daedcae33ced497343f3ca1f2474ad932b903997d44707db41382'.decode('hex') 664 print('XTS %d testing:' % (len(key) * 8)) 665 c = Crypto(CRYPTO_AES_XTS, key) 666 for i in [ 8192, 192*1024]: 667 print('block size: %d' % i) 668 c.perftest(COP_ENCRYPT, i) 669 c.perftest(COP_DECRYPT, i) 670