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