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