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 re 42import signal 43from struct import pack as _pack 44import sys 45import time 46 47import dpkt 48 49from cryptodevh import * 50 51__all__ = [ 'Crypto', 'MismatchError', ] 52 53class FindOp(dpkt.Packet): 54 __byte_order__ = '@' 55 __hdr__ = ( 56 ('crid', 'i', 0), 57 ('name', '32s', 0), 58 ) 59 60class SessionOp(dpkt.Packet): 61 __byte_order__ = '@' 62 __hdr__ = ( 63 ('cipher', 'I', 0), 64 ('mac', 'I', 0), 65 ('keylen', 'I', 0), 66 ('key', 'P', 0), 67 ('mackeylen', 'i', 0), 68 ('mackey', 'P', 0), 69 ('ses', 'I', 0), 70 ) 71 72class SessionOp2(dpkt.Packet): 73 __byte_order__ = '@' 74 __hdr__ = ( 75 ('cipher', 'I', 0), 76 ('mac', 'I', 0), 77 ('keylen', 'I', 0), 78 ('key', 'P', 0), 79 ('mackeylen', 'i', 0), 80 ('mackey', 'P', 0), 81 ('ses', 'I', 0), 82 ('crid', 'i', 0), 83 ('ivlen', 'i', 0), 84 ('maclen', 'i', 0), 85 ('pad0', 'i', 0), 86 ('pad1', 'i', 0), 87 ) 88 89class CryptOp(dpkt.Packet): 90 __byte_order__ = '@' 91 __hdr__ = ( 92 ('ses', 'I', 0), 93 ('op', 'H', 0), 94 ('flags', 'H', 0), 95 ('len', 'I', 0), 96 ('src', 'P', 0), 97 ('dst', 'P', 0), 98 ('mac', 'P', 0), 99 ('iv', 'P', 0), 100 ) 101 102class CryptAEAD(dpkt.Packet): 103 __byte_order__ = '@' 104 __hdr__ = ( 105 ('ses', 'I', 0), 106 ('op', 'H', 0), 107 ('flags', 'H', 0), 108 ('len', 'I', 0), 109 ('aadlen', 'I', 0), 110 ('ivlen', 'I', 0), 111 ('src', 'P', 0), 112 ('dst', 'P', 0), 113 ('aad', 'P', 0), 114 ('tag', 'P', 0), 115 ('iv', 'P', 0), 116 ) 117 118# h2py.py can't handle multiarg macros 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 134_cryptodev = os.open('/dev/crypto', os.O_RDWR) 135 136def str_to_ascii(val): 137 if sys.version_info[0] >= 3: 138 if isinstance(val, str): 139 return val.encode("ascii") 140 return val 141 142def _findop(crid, name): 143 fop = FindOp() 144 fop.crid = crid 145 fop.name = str_to_ascii(name) 146 s = array.array('B', fop.pack_hdr()) 147 ioctl(_cryptodev, CIOCFINDDEV, s, 1) 148 fop.unpack(s) 149 150 try: 151 idx = fop.name.index(b'\x00') 152 name = fop.name[:idx] 153 except ValueError: 154 name = fop.name 155 156 return fop.crid, name 157 158def array_tobytes(array_obj): 159 if sys.version_info[:2] >= (3, 2): 160 return array_obj.tobytes() 161 return array_obj.tostring() 162 163def empty_bytes(): 164 if sys.version_info[0] >= 3: 165 return b'' 166 return "" 167 168class Crypto: 169 @staticmethod 170 def findcrid(name): 171 return _findop(-1, name)[0] 172 173 @staticmethod 174 def getcridname(crid): 175 return _findop(crid, '')[1] 176 177 def __init__(self, cipher=0, key=None, mac=0, mackey=None, 178 crid=CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE, maclen=None, 179 ivlen=None): 180 self._ses = None 181 self._maclen = maclen 182 ses = SessionOp2() 183 ses.cipher = cipher 184 ses.mac = mac 185 186 if key is not None: 187 ses.keylen = len(key) 188 k = array.array('B', key) 189 ses.key = k.buffer_info()[0] 190 else: 191 self.key = None 192 193 if mackey is not None: 194 ses.mackeylen = len(mackey) 195 mk = array.array('B', mackey) 196 ses.mackey = mk.buffer_info()[0] 197 198 if not cipher and not mac: 199 raise ValueError('one of cipher or mac MUST be specified.') 200 ses.crid = crid 201 if ivlen: 202 ses.ivlen = ivlen 203 if maclen: 204 ses.maclen = maclen 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, mac=None): 224 cop = CryptOp() 225 cop.ses = self._ses 226 cop.op = op 227 cop.flags = 0 228 if src is not None: 229 cop.len = len(src) 230 s = array.array('B', src) 231 cop.src = cop.dst = s.buffer_info()[0] 232 if mac is not None: 233 assert len(mac) == self._maclen, \ 234 '%d != %d' % (len(tag), self._maclen) 235 if self._maclen is not None: 236 if mac is None: 237 m = array.array('B', [0] * self._maclen) 238 else: 239 m = array.array('B', mac) 240 cop.mac = m.buffer_info()[0] 241 ivbuf = array.array('B', str_to_ascii(iv)) 242 cop.iv = ivbuf.buffer_info()[0] 243 244 #print('cop:', cop) 245 ioctl(_cryptodev, CIOCCRYPT, bytes(cop)) 246 247 if src is not None: 248 s = array_tobytes(s) 249 else: 250 s = empty_bytes() 251 if self._maclen is not None: 252 return s, array_tobytes(m) 253 254 return s 255 256 def _doaead(self, op, src, aad, iv, tag=None): 257 caead = CryptAEAD() 258 caead.ses = self._ses 259 caead.op = op 260 caead.flags = CRD_F_IV_EXPLICIT 261 caead.flags = 0 262 if src: 263 src = str_to_ascii(src) 264 caead.len = len(src) 265 s = array.array('B', src) 266 caead.src = caead.dst = s.buffer_info()[0] 267 aad = str_to_ascii(aad) 268 caead.aadlen = len(aad) 269 saad = array.array('B', aad) 270 caead.aad = saad.buffer_info()[0] 271 272 if self._maclen is None: 273 raise ValueError('must have a tag length') 274 275 tag = str_to_ascii(tag) 276 if tag is None: 277 tag = array.array('B', [0] * self._maclen) 278 else: 279 assert len(tag) == self._maclen, \ 280 '%d != %d' % (len(tag), self._maclen) 281 tag = array.array('B', tag) 282 283 caead.tag = tag.buffer_info()[0] 284 285 ivbuf = array.array('B', iv) 286 caead.ivlen = len(iv) 287 caead.iv = ivbuf.buffer_info()[0] 288 289 ioctl(_cryptodev, CIOCCRYPTAEAD, bytes(caead)) 290 291 if src: 292 s = array_tobytes(s) 293 else: 294 s = empty_bytes() 295 296 return s, array_tobytes(tag) 297 298 def perftest(self, op, size, timeo=3): 299 inp = array.array('B', (random.randint(0, 255) for x in range(size))) 300 inp = str_to_ascii(inp) 301 out = array.array('B', inp) 302 303 # prep ioctl 304 cop = CryptOp() 305 cop.ses = self._ses 306 cop.op = op 307 cop.flags = 0 308 cop.len = len(inp) 309 s = array.array('B', inp) 310 cop.src = s.buffer_info()[0] 311 cop.dst = out.buffer_info()[0] 312 if self._maclen is not None: 313 m = array.array('B', [0] * self._maclen) 314 cop.mac = m.buffer_info()[0] 315 ivbuf = array.array('B', (random.randint(0, 255) for x in range(16))) 316 cop.iv = ivbuf.buffer_info()[0] 317 318 exit = [ False ] 319 def alarmhandle(a, b, exit=exit): 320 exit[0] = True 321 322 oldalarm = signal.signal(signal.SIGALRM, alarmhandle) 323 signal.alarm(timeo) 324 325 start = time.time() 326 reps = 0 327 cop = bytes(cop) 328 while not exit[0]: 329 ioctl(_cryptodev, CIOCCRYPT, cop) 330 reps += 1 331 332 end = time.time() 333 334 signal.signal(signal.SIGALRM, oldalarm) 335 336 print('time:', end - start) 337 print('perf MB/sec:', (reps * size) / (end - start) / 1024 / 1024) 338 339 def encrypt(self, data, iv, aad=None): 340 if aad is None: 341 return self._doop(COP_ENCRYPT, data, iv) 342 else: 343 return self._doaead(COP_ENCRYPT, data, aad, 344 iv) 345 346 def decrypt(self, data, iv, aad=None, tag=None): 347 if aad is None: 348 return self._doop(COP_DECRYPT, data, iv, mac=tag) 349 else: 350 return self._doaead(COP_DECRYPT, data, aad, 351 iv, tag=tag) 352 353class MismatchError(Exception): 354 pass 355 356class KATParser: 357 def __init__(self, fname, fields): 358 self.fields = set(fields) 359 self._pending = None 360 self.fname = fname 361 self.fp = None 362 self.field_re = re.compile(r"\[(?P<field>[^]]+)\]") 363 364 def __enter__(self): 365 self.fp = open(self.fname) 366 return self 367 368 def __exit__(self, exc_type, exc_value, exc_tb): 369 if self.fp is not None: 370 self.fp.close() 371 372 def __iter__(self): 373 return self 374 375 def __next__(self): 376 while True: 377 while True: 378 if self._pending is not None: 379 i = self._pending 380 self._pending = None 381 else: 382 i = self.fp.readline() 383 if not i: 384 return 385 386 if not i.startswith('#') and i.strip(): 387 break 388 389 matches = self.field_re.match(i) 390 if matches is None: 391 raise ValueError("Unknown line: %r" % (i)) 392 yield matches.group("field"), self.fielditer() 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