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