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