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