]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/sys/opencrypto/cryptodev.py
Fix `KAT(CCM)?Parser` file descriptor leaks
[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
528 def _spdechex(s):
529     return binascii.hexlify(''.join(s.split()))
530
531 if sys.version_info[0] < 3:
532     KATCCMParser.next = KATCCMParser.__next__
533     KATParser.next = KATParser.__next__
534
535 if __name__ == '__main__':
536     if True:
537         try:
538             crid = Crypto.findcrid('aesni0')
539             print('aesni:', crid)
540         except IOError:
541             print('aesni0 not found')
542
543         for i in range(10):
544             try:
545                 name = Crypto.getcridname(i)
546                 print('%2d: %r' % (i, repr(name)))
547             except IOError:
548                 pass
549     elif False:
550         columns = [ 'COUNT', 'DataUnitLen', 'Key', 'DataUnitSeqNumber', 'PT', 'CT' ]
551         fname = '/usr/home/jmg/aesni.testing/format tweak value input - data unit seq no/XTSGenAES128.rsp'
552         with KATParser(fname, columns) as kp:
553             for mode, ni in kp:
554                 print(i, ni)
555                 for j in ni:
556                     print(j)
557     elif False:
558         key = _spdechex('c939cc13397c1d37de6ae0e1cb7c423c')
559         iv = _spdechex('00000000000000000000000000000001')
560         pt = _spdechex('ab3cabed693a32946055524052afe3c9cb49664f09fc8b7da824d924006b7496353b8c1657c5dec564d8f38d7432e1de35aae9d95590e66278d4acce883e51abaf94977fcd3679660109a92bf7b2973ccd547f065ec6cee4cb4a72a5e9f45e615d920d76cb34cba482467b3e21422a7242e7d931330c0fbf465c3a3a46fae943029fd899626dda542750a1eee253df323c6ef1573f1c8c156613e2ea0a6cdbf2ae9701020be2d6a83ecb7f3f9d8e')
561         #pt = _spdechex('00000000000000000000000000000000')
562         ct = _spdechex('f42c33853ecc5ce2949865fdb83de3bff1089e9360c94f830baebfaff72836ab5236f77212f1e7396c8c54ac73d81986375a6e9e299cfeca5ba051ed25e8d1affa5beaf6c1d2b45e90802408f2ced21663497e906de5f29341e5e52ddfea5363d628b3eb7806835e17bae051b3a6da3f8e2941fe44384eac17a9d298d2c331ca8320c775b5d53263a5e905059d891b21dede2d8110fd427c7bd5a9a274ddb47b1945ee79522203b6e297d0e399ef')
563
564         c = Crypto(CRYPTO_AES_ICM, key)
565         enc = c.encrypt(pt, iv)
566
567         print('enc:', binascii.hexlify(enc))
568         print(' ct:', binascii.hexlify(ct))
569
570         assert ct == enc
571
572         dec = c.decrypt(ct, iv)
573
574         print('dec:', binascii.hexlify(dec))
575         print(' pt:', binascii.hexlify(pt))
576
577         assert pt == dec
578     elif False:
579         key = _spdechex('c939cc13397c1d37de6ae0e1cb7c423c')
580         iv = _spdechex('00000000000000000000000000000001')
581         pt = _spdechex('ab3cabed693a32946055524052afe3c9cb49664f09fc8b7da824d924006b7496353b8c1657c5dec564d8f38d7432e1de35aae9d95590e66278d4acce883e51abaf94977fcd3679660109a92bf7b2973ccd547f065ec6cee4cb4a72a5e9f45e615d920d76cb34cba482467b3e21422a7242e7d931330c0fbf465c3a3a46fae943029fd899626dda542750a1eee253df323c6ef1573f1c8c156613e2ea0a6cdbf2ae9701020be2d6a83ecb7f3f9d8e0a3f')
582         #pt = _spdechex('00000000000000000000000000000000')
583         ct = _spdechex('f42c33853ecc5ce2949865fdb83de3bff1089e9360c94f830baebfaff72836ab5236f77212f1e7396c8c54ac73d81986375a6e9e299cfeca5ba051ed25e8d1affa5beaf6c1d2b45e90802408f2ced21663497e906de5f29341e5e52ddfea5363d628b3eb7806835e17bae051b3a6da3f8e2941fe44384eac17a9d298d2c331ca8320c775b5d53263a5e905059d891b21dede2d8110fd427c7bd5a9a274ddb47b1945ee79522203b6e297d0e399ef3768')
584
585         c = Crypto(CRYPTO_AES_ICM, key)
586         enc = c.encrypt(pt, iv)
587
588         print('enc:', binascii.hexlify(enc))
589         print(' ct:', binascii.hexlify(ct))
590
591         assert ct == enc
592
593         dec = c.decrypt(ct, iv)
594
595         print('dec:', binascii.hexlify(dec))
596         print(' pt:', binascii.hexlify(pt))
597
598         assert pt == dec
599     elif False:
600         key = _spdechex('c939cc13397c1d37de6ae0e1cb7c423c')
601         iv = _spdechex('6eba2716ec0bd6fa5cdef5e6d3a795bc')
602         pt = _spdechex('ab3cabed693a32946055524052afe3c9cb49664f09fc8b7da824d924006b7496353b8c1657c5dec564d8f38d7432e1de35aae9d95590e66278d4acce883e51abaf94977fcd3679660109a92bf7b2973ccd547f065ec6cee4cb4a72a5e9f45e615d920d76cb34cba482467b3e21422a7242e7d931330c0fbf465c3a3a46fae943029fd899626dda542750a1eee253df323c6ef1573f1c8c156613e2ea0a6cdbf2ae9701020be2d6a83ecb7f3f9d8e0a3f')
603         ct = _spdechex('f1f81f12e72e992dbdc304032705dc75dc3e4180eff8ee4819906af6aee876d5b00b7c36d282a445ce3620327be481e8e53a8e5a8e5ca9abfeb2281be88d12ffa8f46d958d8224738c1f7eea48bda03edbf9adeb900985f4fa25648b406d13a886c25e70cfdecdde0ad0f2991420eb48a61c64fd797237cf2798c2675b9bb744360b0a3f329ac53bbceb4e3e7456e6514f1a9d2f06c236c31d0f080b79c15dce1096357416602520daa098b17d1af427')
604         c = Crypto(CRYPTO_AES_CBC, key)
605
606         enc = c.encrypt(pt, iv)
607
608         print('enc:', binascii.hexlify(enc))
609         print(' ct:', binascii.hexlify(ct))
610
611         assert ct == enc
612
613         dec = c.decrypt(ct, iv)
614
615         print('dec:', binascii.hexlify(dec))
616         print(' pt:', binascii.hexlify(pt))
617
618         assert pt == dec
619     elif False:
620         key = _spdechex('c939cc13397c1d37de6ae0e1cb7c423c')
621         iv = _spdechex('b3d8cc017cbb89b39e0f67e2')
622         pt = _spdechex('c3b3c41f113a31b73d9a5cd4321030')
623         aad = _spdechex('24825602bd12a984e0092d3e448eda5f')
624         ct = _spdechex('93fe7d9e9bfd10348a5606e5cafa7354')
625         ct = _spdechex('93fe7d9e9bfd10348a5606e5cafa73')
626         tag = _spdechex('0032a1dc85f1c9786925a2e71d8272dd')
627         tag = _spdechex('8d11a0929cb3fbe1fef01a4a38d5f8ea')
628
629         c = Crypto(CRYPTO_AES_NIST_GCM_16, key,
630             mac=CRYPTO_AES_128_NIST_GMAC, mackey=key)
631
632         enc, enctag = c.encrypt(pt, iv, aad=aad)
633
634         print('enc:', binascii.hexlify(enc))
635         print(' ct:', binascii.hexlify(ct))
636
637         assert enc == ct
638
639         print('etg:', binascii.hexlify(enctag))
640         print('tag:', binascii.hexlify(tag))
641         assert enctag == tag
642
643         # Make sure we get EBADMSG
644         #enctag = enctag[:-1] + 'a'
645         dec, dectag = c.decrypt(ct, iv, aad=aad, tag=enctag)
646
647         print('dec:', binascii.hexlify(dec))
648         print(' pt:', binascii.hexlify(pt))
649
650         assert dec == pt
651
652         print('dtg:', binascii.hexlify(dectag))
653         print('tag:', binascii.hexlify(tag))
654
655         assert dectag == tag
656     elif False:
657         key = _spdechex('c939cc13397c1d37de6ae0e1cb7c423c')
658         iv = _spdechex('b3d8cc017cbb89b39e0f67e2')
659         key = key + iv[:4]
660         iv = iv[4:]
661         pt = _spdechex('c3b3c41f113a31b73d9a5cd432103069')
662         aad = _spdechex('24825602bd12a984e0092d3e448eda5f')
663         ct = _spdechex('93fe7d9e9bfd10348a5606e5cafa7354')
664         tag = _spdechex('0032a1dc85f1c9786925a2e71d8272dd')
665
666         c = Crypto(CRYPTO_AES_GCM_16, key, mac=CRYPTO_AES_128_GMAC, mackey=key)
667
668         enc, enctag = c.encrypt(pt, iv, aad=aad)
669
670         print('enc:', binascii.hexlify(enc))
671         print(' ct:', binascii.hexlify(ct))
672
673         assert enc == ct
674
675         print('etg:', binascii.hexlify(enctag))
676         print('tag:', binascii.hexlify(tag))
677         assert enctag == tag
678     elif False:
679         for i in range(100000):
680             c = Crypto(CRYPTO_AES_XTS, binascii.unhexlify('1bbfeadf539daedcae33ced497343f3ca1f2474ad932b903997d44707db41382'))
681             data = binascii.unhexlify('52a42bca4e9425a25bbc8c8bf6129dec')
682             ct = binascii.unhexlify('517e602becd066b65fa4f4f56ddfe240')
683             iv = _pack('QQ', 71, 0)
684
685             enc = c.encrypt(data, iv)
686             assert enc == ct
687     elif True:
688         c = Crypto(CRYPTO_AES_XTS, binascii.unhexlify('1bbfeadf539daedcae33ced497343f3ca1f2474ad932b903997d44707db41382'))
689         data = binascii.unhexlify('52a42bca4e9425a25bbc8c8bf6129dec')
690         ct = binascii.unhexlify('517e602becd066b65fa4f4f56ddfe240')
691         iv = _pack('QQ', 71, 0)
692
693         enc = c.encrypt(data, iv)
694         assert enc == ct
695
696         dec = c.decrypt(enc, iv)
697         assert dec == data
698
699         #c.perftest(COP_ENCRYPT, 192*1024, reps=30000)
700
701     else:
702         key = binascii.unhexlify('1bbfeadf539daedcae33ced497343f3ca1f2474ad932b903997d44707db41382')
703         print('XTS %d testing:' % (len(key) * 8))
704         c = Crypto(CRYPTO_AES_XTS, key)
705         for i in [ 8192, 192*1024]:
706             print('block size: %d' % i)
707             c.perftest(COP_ENCRYPT, i)
708             c.perftest(COP_DECRYPT, i)