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