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