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