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