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 ('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 is not None and len(src) != 0: 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 is not None: 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 362 def __enter__(self): 363 self.fp = open(self.fname) 364 return self 365 366 def __exit__(self, exc_type, exc_value, exc_tb): 367 if self.fp is not None: 368 self.fp.close() 369 370 def __iter__(self): 371 return self 372 373 def __next__(self): 374 while True: 375 didread = False 376 if self._pending is not None: 377 i = self._pending 378 self._pending = None 379 else: 380 i = self.fp.readline() 381 didread = True 382 383 if didread and not i: 384 return 385 386 if not i.startswith('#') and i.strip(): 387 break 388 389 if i[0] == '[': 390 yield i[1:].split(']', 1)[0], self.fielditer() 391 else: 392 raise ValueError('unknown line: %r' % repr(i)) 393 394 def eatblanks(self): 395 while True: 396 line = self.fp.readline() 397 if line == '': 398 break 399 400 line = line.strip() 401 if line: 402 break 403 404 return line 405 406 def fielditer(self): 407 while True: 408 values = {} 409 410 line = self.eatblanks() 411 if not line or line[0] == '[': 412 self._pending = line 413 return 414 415 while True: 416 try: 417 f, v = line.split(' =') 418 except: 419 if line == 'FAIL': 420 f, v = 'FAIL', '' 421 else: 422 print('line:', repr(line)) 423 raise 424 v = v.strip() 425 426 if f in values: 427 raise ValueError('already present: %r' % repr(f)) 428 values[f] = v 429 line = self.fp.readline().strip() 430 if not line: 431 break 432 433 # we should have everything 434 remain = self.fields.copy() - set(values.keys()) 435 # XXX - special case GCM decrypt 436 if remain and not ('FAIL' in values and 'PT' in remain): 437 raise ValueError('not all fields found: %r' % repr(remain)) 438 439 yield values 440 441# The CCM files use a bit of a different syntax that doesn't quite fit 442# the generic KATParser. In particular, some keys are set globally at 443# the start of the file, and some are set globally at the start of a 444# section. 445class KATCCMParser: 446 def __init__(self, fname): 447 self._pending = None 448 self.fname = fname 449 self.fp = None 450 451 def __enter__(self): 452 self.fp = open(self.fname) 453 self.read_globals() 454 return self 455 456 def __exit__(self, exc_type, exc_value, exc_tb): 457 if self.fp is not None: 458 self.fp.close() 459 460 def read_globals(self): 461 self.global_values = {} 462 while True: 463 line = self.fp.readline() 464 if not line: 465 return 466 if line[0] == '#' or not line.strip(): 467 continue 468 if line[0] == '[': 469 self._pending = line 470 return 471 472 try: 473 f, v = line.split(' =') 474 except: 475 print('line:', repr(line)) 476 raise 477 478 v = v.strip() 479 480 if f in self.global_values: 481 raise ValueError('already present: %r' % repr(f)) 482 self.global_values[f] = v 483 484 def read_section_values(self, kwpairs): 485 self.section_values = self.global_values.copy() 486 for pair in kwpairs.split(', '): 487 f, v = pair.split(' = ') 488 if f in self.section_values: 489 raise ValueError('already present: %r' % repr(f)) 490 self.section_values[f] = v 491 492 while True: 493 line = self.fp.readline() 494 if not line: 495 return 496 if line[0] == '#' or not line.strip(): 497 continue 498 if line[0] == '[': 499 self._pending = line 500 return 501 502 try: 503 f, v = line.split(' =') 504 except: 505 print('line:', repr(line)) 506 raise 507 508 if f == 'Count': 509 self._pending = line 510 return 511 512 v = v.strip() 513 514 if f in self.section_values: 515 raise ValueError('already present: %r' % repr(f)) 516 self.section_values[f] = v 517 518 def __iter__(self): 519 return self 520 521 def __next__(self): 522 while True: 523 if self._pending: 524 line = self._pending 525 self._pending = None 526 else: 527 line = self.fp.readline() 528 if not line: 529 return 530 531 if (line and line[0] == '#') or not line.strip(): 532 continue 533 534 if line[0] == '[': 535 section = line[1:].split(']', 1)[0] 536 self.read_section_values(section) 537 continue 538 539 values = self.section_values.copy() 540 541 while True: 542 try: 543 f, v = line.split(' =') 544 except: 545 print('line:', repr(line)) 546 raise 547 v = v.strip() 548 549 if f in values: 550 raise ValueError('already present: %r' % repr(f)) 551 values[f] = v 552 line = self.fp.readline().strip() 553 if not line: 554 break 555 556 yield values 557 558def _spdechex(s): 559 return binascii.hexlify(''.join(s.split())) 560 561if sys.version_info[0] < 3: 562 KATCCMParser.next = KATCCMParser.__next__ 563 KATParser.next = KATParser.__next__ 564 565if __name__ == '__main__': 566 if True: 567 try: 568 crid = Crypto.findcrid('aesni0') 569 print('aesni:', crid) 570 except IOError: 571 print('aesni0 not found') 572 573 for i in range(10): 574 try: 575 name = Crypto.getcridname(i) 576 print('%2d: %r' % (i, repr(name))) 577 except IOError: 578 pass 579 elif False: 580 columns = [ 'COUNT', 'DataUnitLen', 'Key', 'DataUnitSeqNumber', 'PT', 'CT' ] 581 fname = '/usr/home/jmg/aesni.testing/format tweak value input - data unit seq no/XTSGenAES128.rsp' 582 with KATParser(fname, columns) as kp: 583 for mode, ni in kp: 584 print(i, ni) 585 for j in ni: 586 print(j) 587 elif False: 588 key = _spdechex('c939cc13397c1d37de6ae0e1cb7c423c') 589 iv = _spdechex('00000000000000000000000000000001') 590 pt = _spdechex('ab3cabed693a32946055524052afe3c9cb49664f09fc8b7da824d924006b7496353b8c1657c5dec564d8f38d7432e1de35aae9d95590e66278d4acce883e51abaf94977fcd3679660109a92bf7b2973ccd547f065ec6cee4cb4a72a5e9f45e615d920d76cb34cba482467b3e21422a7242e7d931330c0fbf465c3a3a46fae943029fd899626dda542750a1eee253df323c6ef1573f1c8c156613e2ea0a6cdbf2ae9701020be2d6a83ecb7f3f9d8e') 591 #pt = _spdechex('00000000000000000000000000000000') 592 ct = _spdechex('f42c33853ecc5ce2949865fdb83de3bff1089e9360c94f830baebfaff72836ab5236f77212f1e7396c8c54ac73d81986375a6e9e299cfeca5ba051ed25e8d1affa5beaf6c1d2b45e90802408f2ced21663497e906de5f29341e5e52ddfea5363d628b3eb7806835e17bae051b3a6da3f8e2941fe44384eac17a9d298d2c331ca8320c775b5d53263a5e905059d891b21dede2d8110fd427c7bd5a9a274ddb47b1945ee79522203b6e297d0e399ef') 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('00000000000000000000000000000001') 611 pt = _spdechex('ab3cabed693a32946055524052afe3c9cb49664f09fc8b7da824d924006b7496353b8c1657c5dec564d8f38d7432e1de35aae9d95590e66278d4acce883e51abaf94977fcd3679660109a92bf7b2973ccd547f065ec6cee4cb4a72a5e9f45e615d920d76cb34cba482467b3e21422a7242e7d931330c0fbf465c3a3a46fae943029fd899626dda542750a1eee253df323c6ef1573f1c8c156613e2ea0a6cdbf2ae9701020be2d6a83ecb7f3f9d8e0a3f') 612 #pt = _spdechex('00000000000000000000000000000000') 613 ct = _spdechex('f42c33853ecc5ce2949865fdb83de3bff1089e9360c94f830baebfaff72836ab5236f77212f1e7396c8c54ac73d81986375a6e9e299cfeca5ba051ed25e8d1affa5beaf6c1d2b45e90802408f2ced21663497e906de5f29341e5e52ddfea5363d628b3eb7806835e17bae051b3a6da3f8e2941fe44384eac17a9d298d2c331ca8320c775b5d53263a5e905059d891b21dede2d8110fd427c7bd5a9a274ddb47b1945ee79522203b6e297d0e399ef3768') 614 615 c = Crypto(CRYPTO_AES_ICM, key) 616 enc = c.encrypt(pt, iv) 617 618 print('enc:', binascii.hexlify(enc)) 619 print(' ct:', binascii.hexlify(ct)) 620 621 assert ct == enc 622 623 dec = c.decrypt(ct, iv) 624 625 print('dec:', binascii.hexlify(dec)) 626 print(' pt:', binascii.hexlify(pt)) 627 628 assert pt == dec 629 elif False: 630 key = _spdechex('c939cc13397c1d37de6ae0e1cb7c423c') 631 iv = _spdechex('6eba2716ec0bd6fa5cdef5e6d3a795bc') 632 pt = _spdechex('ab3cabed693a32946055524052afe3c9cb49664f09fc8b7da824d924006b7496353b8c1657c5dec564d8f38d7432e1de35aae9d95590e66278d4acce883e51abaf94977fcd3679660109a92bf7b2973ccd547f065ec6cee4cb4a72a5e9f45e615d920d76cb34cba482467b3e21422a7242e7d931330c0fbf465c3a3a46fae943029fd899626dda542750a1eee253df323c6ef1573f1c8c156613e2ea0a6cdbf2ae9701020be2d6a83ecb7f3f9d8e0a3f') 633 ct = _spdechex('f1f81f12e72e992dbdc304032705dc75dc3e4180eff8ee4819906af6aee876d5b00b7c36d282a445ce3620327be481e8e53a8e5a8e5ca9abfeb2281be88d12ffa8f46d958d8224738c1f7eea48bda03edbf9adeb900985f4fa25648b406d13a886c25e70cfdecdde0ad0f2991420eb48a61c64fd797237cf2798c2675b9bb744360b0a3f329ac53bbceb4e3e7456e6514f1a9d2f06c236c31d0f080b79c15dce1096357416602520daa098b17d1af427') 634 c = Crypto(CRYPTO_AES_CBC, key) 635 636 enc = c.encrypt(pt, iv) 637 638 print('enc:', binascii.hexlify(enc)) 639 print(' ct:', binascii.hexlify(ct)) 640 641 assert ct == enc 642 643 dec = c.decrypt(ct, iv) 644 645 print('dec:', binascii.hexlify(dec)) 646 print(' pt:', binascii.hexlify(pt)) 647 648 assert pt == dec 649 elif False: 650 key = _spdechex('c939cc13397c1d37de6ae0e1cb7c423c') 651 iv = _spdechex('b3d8cc017cbb89b39e0f67e2') 652 pt = _spdechex('c3b3c41f113a31b73d9a5cd4321030') 653 aad = _spdechex('24825602bd12a984e0092d3e448eda5f') 654 ct = _spdechex('93fe7d9e9bfd10348a5606e5cafa7354') 655 ct = _spdechex('93fe7d9e9bfd10348a5606e5cafa73') 656 tag = _spdechex('0032a1dc85f1c9786925a2e71d8272dd') 657 tag = _spdechex('8d11a0929cb3fbe1fef01a4a38d5f8ea') 658 659 c = Crypto(CRYPTO_AES_NIST_GCM_16, key) 660 661 enc, enctag = c.encrypt(pt, iv, aad=aad) 662 663 print('enc:', binascii.hexlify(enc)) 664 print(' ct:', binascii.hexlify(ct)) 665 666 assert enc == ct 667 668 print('etg:', binascii.hexlify(enctag)) 669 print('tag:', binascii.hexlify(tag)) 670 assert enctag == tag 671 672 # Make sure we get EBADMSG 673 #enctag = enctag[:-1] + 'a' 674 dec, dectag = c.decrypt(ct, iv, aad=aad, tag=enctag) 675 676 print('dec:', binascii.hexlify(dec)) 677 print(' pt:', binascii.hexlify(pt)) 678 679 assert dec == pt 680 681 print('dtg:', binascii.hexlify(dectag)) 682 print('tag:', binascii.hexlify(tag)) 683 684 assert dectag == tag 685 elif False: 686 key = _spdechex('c939cc13397c1d37de6ae0e1cb7c423c') 687 iv = _spdechex('b3d8cc017cbb89b39e0f67e2') 688 key = key + iv[:4] 689 iv = iv[4:] 690 pt = _spdechex('c3b3c41f113a31b73d9a5cd432103069') 691 aad = _spdechex('24825602bd12a984e0092d3e448eda5f') 692 ct = _spdechex('93fe7d9e9bfd10348a5606e5cafa7354') 693 tag = _spdechex('0032a1dc85f1c9786925a2e71d8272dd') 694 695 c = Crypto(CRYPTO_AES_GCM_16, key) 696 697 enc, enctag = c.encrypt(pt, iv, aad=aad) 698 699 print('enc:', binascii.hexlify(enc)) 700 print(' ct:', binascii.hexlify(ct)) 701 702 assert enc == ct 703 704 print('etg:', binascii.hexlify(enctag)) 705 print('tag:', binascii.hexlify(tag)) 706 assert enctag == tag 707 elif False: 708 for i in range(100000): 709 c = Crypto(CRYPTO_AES_XTS, binascii.unhexlify('1bbfeadf539daedcae33ced497343f3ca1f2474ad932b903997d44707db41382')) 710 data = binascii.unhexlify('52a42bca4e9425a25bbc8c8bf6129dec') 711 ct = binascii.unhexlify('517e602becd066b65fa4f4f56ddfe240') 712 iv = _pack('QQ', 71, 0) 713 714 enc = c.encrypt(data, iv) 715 assert enc == ct 716 elif True: 717 c = Crypto(CRYPTO_AES_XTS, binascii.unhexlify('1bbfeadf539daedcae33ced497343f3ca1f2474ad932b903997d44707db41382')) 718 data = binascii.unhexlify('52a42bca4e9425a25bbc8c8bf6129dec') 719 ct = binascii.unhexlify('517e602becd066b65fa4f4f56ddfe240') 720 iv = _pack('QQ', 71, 0) 721 722 enc = c.encrypt(data, iv) 723 assert enc == ct 724 725 dec = c.decrypt(enc, iv) 726 assert dec == data 727 728 #c.perftest(COP_ENCRYPT, 192*1024, reps=30000) 729 730 else: 731 key = binascii.unhexlify('1bbfeadf539daedcae33ced497343f3ca1f2474ad932b903997d44707db41382') 732 print('XTS %d testing:' % (len(key) * 8)) 733 c = Crypto(CRYPTO_AES_XTS, key) 734 for i in [ 8192, 192*1024]: 735 print('block size: %d' % i) 736 c.perftest(COP_ENCRYPT, i) 737 c.perftest(COP_DECRYPT, i) 738