1350209Slwhsu#!/usr/local/bin/python2
2275732Sjmg#
3275732Sjmg# Copyright (c) 2014 The FreeBSD Foundation
4275732Sjmg# Copyright 2014 John-Mark Gurney
5275732Sjmg# All rights reserved.
6275732Sjmg#
7275732Sjmg# This software was developed by John-Mark Gurney under
8275732Sjmg# the sponsorship from the FreeBSD Foundation.
9275732Sjmg# Redistribution and use in source and binary forms, with or without
10275732Sjmg# modification, are permitted provided that the following conditions
11275732Sjmg# are met:
12275732Sjmg# 1.  Redistributions of source code must retain the above copyright
13275732Sjmg#     notice, this list of conditions and the following disclaimer.
14275732Sjmg# 2.  Redistributions in binary form must reproduce the above copyright
15275732Sjmg#     notice, this list of conditions and the following disclaimer in the
16275732Sjmg#     documentation and/or other materials provided with the distribution.
17275732Sjmg#
18275732Sjmg# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19275732Sjmg# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20275732Sjmg# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21275732Sjmg# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22275732Sjmg# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23275732Sjmg# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24275732Sjmg# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25275732Sjmg# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26275732Sjmg# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27275732Sjmg# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28275732Sjmg# SUCH DAMAGE.
29275732Sjmg#
30275732Sjmg# $FreeBSD: stable/11/tests/sys/opencrypto/cryptodev.py 350209 2019-07-22 08:27:44Z lwhsu $
31275732Sjmg#
32275732Sjmg
33275732Sjmgimport array
34275732Sjmgimport dpkt
35275732Sjmgfrom fcntl import ioctl
36275732Sjmgimport os
37350209Slwhsuimport platform
38275732Sjmgimport signal
39275732Sjmgfrom struct import pack as _pack
40275732Sjmg
41275732Sjmgfrom cryptodevh import *
42275732Sjmg
43275732Sjmg__all__ = [ 'Crypto', 'MismatchError', ]
44275732Sjmg
45275732Sjmgclass FindOp(dpkt.Packet):
46275732Sjmg	__byte_order__ = '@'
47275732Sjmg	__hdr__ = ( ('crid', 'i', 0),
48275732Sjmg		('name', '32s', 0),
49275732Sjmg	)
50275732Sjmg
51275732Sjmgclass SessionOp(dpkt.Packet):
52275732Sjmg	__byte_order__ = '@'
53275732Sjmg	__hdr__ = ( ('cipher', 'I', 0),
54275732Sjmg		('mac', 'I', 0),
55275732Sjmg		('keylen', 'I', 0),
56275732Sjmg		('key', 'P', 0),
57275732Sjmg		('mackeylen', 'i', 0),
58275732Sjmg		('mackey', 'P', 0),
59275732Sjmg		('ses', 'I', 0),
60275732Sjmg	)
61275732Sjmg
62275732Sjmgclass SessionOp2(dpkt.Packet):
63275732Sjmg	__byte_order__ = '@'
64275732Sjmg	__hdr__ = ( ('cipher', 'I', 0),
65275732Sjmg		('mac', 'I', 0),
66275732Sjmg		('keylen', 'I', 0),
67275732Sjmg		('key', 'P', 0),
68275732Sjmg		('mackeylen', 'i', 0),
69275732Sjmg		('mackey', 'P', 0),
70275732Sjmg		('ses', 'I', 0),
71275732Sjmg		('crid', 'i', 0),
72275732Sjmg		('pad0', 'i', 0),
73275732Sjmg		('pad1', 'i', 0),
74275732Sjmg		('pad2', 'i', 0),
75275732Sjmg		('pad3', 'i', 0),
76275732Sjmg	)
77275732Sjmg
78275732Sjmgclass CryptOp(dpkt.Packet):
79275732Sjmg	__byte_order__ = '@'
80275732Sjmg	__hdr__ = ( ('ses', 'I', 0),
81275732Sjmg		('op', 'H', 0),
82275732Sjmg		('flags', 'H', 0),
83275732Sjmg		('len', 'I', 0),
84275732Sjmg		('src', 'P', 0),
85275732Sjmg		('dst', 'P', 0),
86275732Sjmg		('mac', 'P', 0),
87275732Sjmg		('iv', 'P', 0),
88275732Sjmg	)
89275732Sjmg
90275732Sjmgclass CryptAEAD(dpkt.Packet):
91275732Sjmg	__byte_order__ = '@'
92275732Sjmg	__hdr__ = (
93275732Sjmg		('ses',		'I', 0),
94275732Sjmg		('op',		'H', 0),
95275732Sjmg		('flags',	'H', 0),
96275732Sjmg		('len',		'I', 0),
97275732Sjmg		('aadlen',	'I', 0),
98275732Sjmg		('ivlen',	'I', 0),
99275732Sjmg		('src',		'P', 0),
100275732Sjmg		('dst',		'P', 0),
101275732Sjmg		('aad',		'P', 0),
102275732Sjmg		('tag',		'P', 0),
103275732Sjmg		('iv',		'P', 0),
104275732Sjmg	)
105275732Sjmg
106275732Sjmg# h2py.py can't handle multiarg macros
107275732SjmgCRIOGET = 3221513060
108275732SjmgCIOCGSESSION = 3224396645
109275732SjmgCIOCFSESSION = 2147771238
110275732SjmgCIOCKEY = 3230688104
111275732SjmgCIOCASYMFEAT = 1074029417
112275732SjmgCIOCKEY2 = 3230688107
113275732SjmgCIOCFINDDEV = 3223610220
114350209Slwhsuif platform.architecture()[0] == '64bit':
115350209Slwhsu    CIOCGSESSION2 = 3225445226
116350209Slwhsu    CIOCCRYPT = 3224396647
117350209Slwhsu    CIOCCRYPTAEAD = 3225445229
118350209Slwhsuelse:
119350209Slwhsu    CIOCGSESSION2 = 3224396650
120350209Slwhsu    CIOCCRYPT = 3223085927
121350209Slwhsu    CIOCCRYPTAEAD = 3223872365
122275732Sjmg
123275732Sjmgdef _getdev():
124275732Sjmg	fd = os.open('/dev/crypto', os.O_RDWR)
125275732Sjmg	buf = array.array('I', [0])
126275732Sjmg	ioctl(fd, CRIOGET, buf, 1)
127275732Sjmg	os.close(fd)
128275732Sjmg
129275732Sjmg	return buf[0]
130275732Sjmg
131275732Sjmg_cryptodev = _getdev()
132275732Sjmg
133275732Sjmgdef _findop(crid, name):
134275732Sjmg	fop = FindOp()
135275732Sjmg	fop.crid = crid
136275732Sjmg	fop.name = name
137275732Sjmg	s = array.array('B', fop.pack_hdr())
138275732Sjmg	ioctl(_cryptodev, CIOCFINDDEV, s, 1)
139275732Sjmg	fop.unpack(s)
140275732Sjmg
141275732Sjmg	try:
142275732Sjmg		idx = fop.name.index('\x00')
143275732Sjmg		name = fop.name[:idx]
144275732Sjmg	except ValueError:
145275732Sjmg		name = fop.name
146275732Sjmg
147275732Sjmg	return fop.crid, name
148275732Sjmg
149275732Sjmgclass Crypto:
150275732Sjmg	@staticmethod
151275732Sjmg	def findcrid(name):
152275732Sjmg		return _findop(-1, name)[0]
153275732Sjmg
154275732Sjmg	@staticmethod
155275732Sjmg	def getcridname(crid):
156275732Sjmg		return _findop(crid, '')[1]
157275732Sjmg
158275732Sjmg	def __init__(self, cipher=0, key=None, mac=0, mackey=None,
159275732Sjmg	    crid=CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE):
160275732Sjmg		self._ses = None
161275732Sjmg		ses = SessionOp2()
162275732Sjmg		ses.cipher = cipher
163275732Sjmg		ses.mac = mac
164275732Sjmg
165275732Sjmg		if key is not None:
166275732Sjmg			ses.keylen = len(key)
167275732Sjmg			k = array.array('B', key)
168275732Sjmg			ses.key = k.buffer_info()[0]
169275732Sjmg		else:
170275732Sjmg			self.key = None
171275732Sjmg
172275732Sjmg		if mackey is not None:
173275732Sjmg			ses.mackeylen = len(mackey)
174275732Sjmg			mk = array.array('B', mackey)
175275732Sjmg			ses.mackey = mk.buffer_info()[0]
176275732Sjmg			self._maclen = 16	# parameterize?
177275732Sjmg		else:
178275732Sjmg			self._maclen = None
179275732Sjmg
180275732Sjmg		if not cipher and not mac:
181275732Sjmg			raise ValueError('one of cipher or mac MUST be specified.')
182329008Sjhb		ses.crid = crid
183275732Sjmg		#print `ses`
184275732Sjmg		s = array.array('B', ses.pack_hdr())
185275732Sjmg		#print `s`
186275732Sjmg		ioctl(_cryptodev, CIOCGSESSION2, s, 1)
187275732Sjmg		ses.unpack(s)
188275732Sjmg
189275732Sjmg		self._ses = ses.ses
190275732Sjmg
191275732Sjmg	def __del__(self):
192275732Sjmg		if self._ses is None:
193275732Sjmg			return
194275732Sjmg
195275732Sjmg		try:
196275732Sjmg			ioctl(_cryptodev, CIOCFSESSION, _pack('I', self._ses))
197275732Sjmg		except TypeError:
198275732Sjmg			pass
199275732Sjmg		self._ses = None
200275732Sjmg
201275732Sjmg	def _doop(self, op, src, iv):
202275732Sjmg		cop = CryptOp()
203275732Sjmg		cop.ses = self._ses
204275732Sjmg		cop.op = op
205275732Sjmg		cop.flags = 0
206275732Sjmg		cop.len = len(src)
207275732Sjmg		s = array.array('B', src)
208275732Sjmg		cop.src = cop.dst = s.buffer_info()[0]
209275732Sjmg		if self._maclen is not None:
210275732Sjmg			m = array.array('B', [0] * self._maclen)
211275732Sjmg			cop.mac = m.buffer_info()[0]
212275732Sjmg		ivbuf = array.array('B', iv)
213275732Sjmg		cop.iv = ivbuf.buffer_info()[0]
214275732Sjmg
215275732Sjmg		#print 'cop:', `cop`
216275732Sjmg		ioctl(_cryptodev, CIOCCRYPT, str(cop))
217275732Sjmg
218275732Sjmg		s = s.tostring()
219275732Sjmg		if self._maclen is not None:
220275732Sjmg			return s, m.tostring()
221275732Sjmg
222275732Sjmg		return s
223275732Sjmg
224275732Sjmg	def _doaead(self, op, src, aad, iv, tag=None):
225275732Sjmg		caead = CryptAEAD()
226275732Sjmg		caead.ses = self._ses
227275732Sjmg		caead.op = op
228275732Sjmg		caead.flags = CRD_F_IV_EXPLICIT
229275732Sjmg		caead.flags = 0
230275732Sjmg		caead.len = len(src)
231275732Sjmg		s = array.array('B', src)
232275732Sjmg		caead.src = caead.dst = s.buffer_info()[0]
233275732Sjmg		caead.aadlen = len(aad)
234275732Sjmg		saad = array.array('B', aad)
235275732Sjmg		caead.aad = saad.buffer_info()[0]
236275732Sjmg
237275732Sjmg		if self._maclen is None:
238275732Sjmg			raise ValueError('must have a tag length')
239275732Sjmg
240275732Sjmg		if tag is None:
241275732Sjmg			tag = array.array('B', [0] * self._maclen)
242275732Sjmg		else:
243275732Sjmg			assert len(tag) == self._maclen, `len(tag), self._maclen`
244275732Sjmg			tag = array.array('B', tag)
245275732Sjmg
246275732Sjmg		caead.tag = tag.buffer_info()[0]
247275732Sjmg
248275732Sjmg		ivbuf = array.array('B', iv)
249275732Sjmg		caead.ivlen = len(iv)
250275732Sjmg		caead.iv = ivbuf.buffer_info()[0]
251275732Sjmg
252275732Sjmg		ioctl(_cryptodev, CIOCCRYPTAEAD, str(caead))
253275732Sjmg
254275732Sjmg		s = s.tostring()
255275732Sjmg
256275732Sjmg		return s, tag.tostring()
257275732Sjmg
258275732Sjmg	def perftest(self, op, size, timeo=3):
259275732Sjmg		import random
260275732Sjmg		import time
261275732Sjmg
262275732Sjmg		inp = array.array('B', (random.randint(0, 255) for x in xrange(size)))
263275732Sjmg		out = array.array('B', inp)
264275732Sjmg
265275732Sjmg		# prep ioctl
266275732Sjmg		cop = CryptOp()
267275732Sjmg		cop.ses = self._ses
268275732Sjmg		cop.op = op
269275732Sjmg		cop.flags = 0
270275732Sjmg		cop.len = len(inp)
271275732Sjmg		s = array.array('B', inp)
272275732Sjmg		cop.src = s.buffer_info()[0]
273275732Sjmg		cop.dst = out.buffer_info()[0]
274275732Sjmg		if self._maclen is not None:
275275732Sjmg			m = array.array('B', [0] * self._maclen)
276275732Sjmg			cop.mac = m.buffer_info()[0]
277275732Sjmg		ivbuf = array.array('B', (random.randint(0, 255) for x in xrange(16)))
278275732Sjmg		cop.iv = ivbuf.buffer_info()[0]
279275732Sjmg
280275732Sjmg		exit = [ False ]
281275732Sjmg		def alarmhandle(a, b, exit=exit):
282275732Sjmg			exit[0] = True
283275732Sjmg
284275732Sjmg		oldalarm = signal.signal(signal.SIGALRM, alarmhandle)
285275732Sjmg		signal.alarm(timeo)
286275732Sjmg
287275732Sjmg		start = time.time()
288275732Sjmg		reps = 0
289275732Sjmg		while not exit[0]:
290275732Sjmg			ioctl(_cryptodev, CIOCCRYPT, str(cop))
291275732Sjmg			reps += 1
292275732Sjmg
293275732Sjmg		end = time.time()
294275732Sjmg
295275732Sjmg		signal.signal(signal.SIGALRM, oldalarm)
296275732Sjmg
297275732Sjmg		print 'time:', end - start
298275732Sjmg		print 'perf MB/sec:', (reps * size) / (end - start) / 1024 / 1024
299275732Sjmg
300275732Sjmg	def encrypt(self, data, iv, aad=None):
301275732Sjmg		if aad is None:
302275732Sjmg			return self._doop(COP_ENCRYPT, data, iv)
303275732Sjmg		else:
304275732Sjmg			return self._doaead(COP_ENCRYPT, data, aad,
305275732Sjmg			    iv)
306275732Sjmg
307275732Sjmg	def decrypt(self, data, iv, aad=None, tag=None):
308275732Sjmg		if aad is None:
309275732Sjmg			return self._doop(COP_DECRYPT, data, iv)
310275732Sjmg		else:
311275732Sjmg			return self._doaead(COP_DECRYPT, data, aad,
312275732Sjmg			    iv, tag=tag)
313275732Sjmg
314275732Sjmgclass MismatchError(Exception):
315275732Sjmg	pass
316275732Sjmg
317275732Sjmgclass KATParser:
318275732Sjmg	def __init__(self, fname, fields):
319275732Sjmg		self.fp = open(fname)
320275732Sjmg		self.fields = set(fields)
321275732Sjmg		self._pending = None
322275732Sjmg
323275732Sjmg	def __iter__(self):
324275732Sjmg		while True:
325275732Sjmg			didread = False
326275732Sjmg			if self._pending is not None:
327275732Sjmg				i = self._pending
328275732Sjmg				self._pending = None
329275732Sjmg			else:
330275732Sjmg				i = self.fp.readline()
331275732Sjmg				didread = True
332275732Sjmg
333275732Sjmg			if didread and not i:
334275732Sjmg				return
335275732Sjmg
336275732Sjmg			if (i and i[0] == '#') or not i.strip():
337275732Sjmg				continue
338275732Sjmg			if i[0] == '[':
339275732Sjmg				yield i[1:].split(']', 1)[0], self.fielditer()
340275732Sjmg			else:
341275732Sjmg				raise ValueError('unknown line: %s' % `i`)
342275732Sjmg
343275732Sjmg	def eatblanks(self):
344275732Sjmg		while True:
345275732Sjmg			line = self.fp.readline()
346275732Sjmg			if line == '':
347275732Sjmg				break
348275732Sjmg
349275732Sjmg			line = line.strip()
350275732Sjmg			if line:
351275732Sjmg				break
352275732Sjmg
353275732Sjmg		return line
354275732Sjmg
355275732Sjmg	def fielditer(self):
356275732Sjmg		while True:
357275732Sjmg			values = {}
358275732Sjmg
359275732Sjmg			line = self.eatblanks()
360275732Sjmg			if not line or line[0] == '[':
361275732Sjmg				self._pending = line
362275732Sjmg				return
363275732Sjmg
364275732Sjmg			while True:
365275732Sjmg				try:
366275732Sjmg					f, v = line.split(' =')
367275732Sjmg				except:
368275732Sjmg					if line == 'FAIL':
369275732Sjmg						f, v = 'FAIL', ''
370275732Sjmg					else:
371275732Sjmg						print 'line:', `line`
372275732Sjmg						raise
373275732Sjmg				v = v.strip()
374275732Sjmg
375275732Sjmg				if f in values:
376275732Sjmg					raise ValueError('already present: %s' % `f`)
377275732Sjmg				values[f] = v
378275732Sjmg				line = self.fp.readline().strip()
379275732Sjmg				if not line:
380275732Sjmg					break
381275732Sjmg
382275732Sjmg			# we should have everything
383275732Sjmg			remain = self.fields.copy() - set(values.keys())
384275732Sjmg			# XXX - special case GCM decrypt
385275732Sjmg			if remain and not ('FAIL' in values and 'PT' in remain):
386275732Sjmg					raise ValueError('not all fields found: %s' % `remain`)
387275732Sjmg
388275732Sjmg			yield values
389275732Sjmg
390275732Sjmgdef _spdechex(s):
391275732Sjmg	return ''.join(s.split()).decode('hex')
392275732Sjmg
393275732Sjmgif __name__ == '__main__':
394275732Sjmg	if True:
395275732Sjmg		try:
396275732Sjmg			crid = Crypto.findcrid('aesni0')
397275732Sjmg			print 'aesni:', crid
398275732Sjmg		except IOError:
399275732Sjmg			print 'aesni0 not found'
400275732Sjmg
401275732Sjmg		for i in xrange(10):
402275732Sjmg			try:
403275732Sjmg				name = Crypto.getcridname(i)
404275732Sjmg				print '%2d: %s' % (i, `name`)
405275732Sjmg			except IOError:
406275732Sjmg				pass
407275732Sjmg	elif False:
408275732Sjmg		kp = KATParser('/usr/home/jmg/aesni.testing/format tweak value input - data unit seq no/XTSGenAES128.rsp', [ 'COUNT', 'DataUnitLen', 'Key', 'DataUnitSeqNumber', 'PT', 'CT' ])
409275732Sjmg		for mode, ni in kp:
410275732Sjmg			print `i`, `ni`
411275732Sjmg			for j in ni:
412275732Sjmg				print `j`
413275732Sjmg	elif False:
414275732Sjmg		key = _spdechex('c939cc13397c1d37de6ae0e1cb7c423c')
415275732Sjmg		iv = _spdechex('00000000000000000000000000000001')
416275732Sjmg		pt = _spdechex('ab3cabed693a32946055524052afe3c9cb49664f09fc8b7da824d924006b7496353b8c1657c5dec564d8f38d7432e1de35aae9d95590e66278d4acce883e51abaf94977fcd3679660109a92bf7b2973ccd547f065ec6cee4cb4a72a5e9f45e615d920d76cb34cba482467b3e21422a7242e7d931330c0fbf465c3a3a46fae943029fd899626dda542750a1eee253df323c6ef1573f1c8c156613e2ea0a6cdbf2ae9701020be2d6a83ecb7f3f9d8e')
417275732Sjmg		#pt = _spdechex('00000000000000000000000000000000')
418275732Sjmg		ct = _spdechex('f42c33853ecc5ce2949865fdb83de3bff1089e9360c94f830baebfaff72836ab5236f77212f1e7396c8c54ac73d81986375a6e9e299cfeca5ba051ed25e8d1affa5beaf6c1d2b45e90802408f2ced21663497e906de5f29341e5e52ddfea5363d628b3eb7806835e17bae051b3a6da3f8e2941fe44384eac17a9d298d2c331ca8320c775b5d53263a5e905059d891b21dede2d8110fd427c7bd5a9a274ddb47b1945ee79522203b6e297d0e399ef')
419275732Sjmg
420275732Sjmg		c = Crypto(CRYPTO_AES_ICM, key)
421275732Sjmg		enc = c.encrypt(pt, iv)
422275732Sjmg
423275732Sjmg		print 'enc:', enc.encode('hex')
424275732Sjmg		print ' ct:', ct.encode('hex')
425275732Sjmg
426275732Sjmg		assert ct == enc
427275732Sjmg
428275732Sjmg		dec = c.decrypt(ct, iv)
429275732Sjmg
430275732Sjmg		print 'dec:', dec.encode('hex')
431275732Sjmg		print ' pt:', pt.encode('hex')
432275732Sjmg
433275732Sjmg		assert pt == dec
434275732Sjmg	elif False:
435275732Sjmg		key = _spdechex('c939cc13397c1d37de6ae0e1cb7c423c')
436275732Sjmg		iv = _spdechex('00000000000000000000000000000001')
437275732Sjmg		pt = _spdechex('ab3cabed693a32946055524052afe3c9cb49664f09fc8b7da824d924006b7496353b8c1657c5dec564d8f38d7432e1de35aae9d95590e66278d4acce883e51abaf94977fcd3679660109a92bf7b2973ccd547f065ec6cee4cb4a72a5e9f45e615d920d76cb34cba482467b3e21422a7242e7d931330c0fbf465c3a3a46fae943029fd899626dda542750a1eee253df323c6ef1573f1c8c156613e2ea0a6cdbf2ae9701020be2d6a83ecb7f3f9d8e0a3f')
438275732Sjmg		#pt = _spdechex('00000000000000000000000000000000')
439275732Sjmg		ct = _spdechex('f42c33853ecc5ce2949865fdb83de3bff1089e9360c94f830baebfaff72836ab5236f77212f1e7396c8c54ac73d81986375a6e9e299cfeca5ba051ed25e8d1affa5beaf6c1d2b45e90802408f2ced21663497e906de5f29341e5e52ddfea5363d628b3eb7806835e17bae051b3a6da3f8e2941fe44384eac17a9d298d2c331ca8320c775b5d53263a5e905059d891b21dede2d8110fd427c7bd5a9a274ddb47b1945ee79522203b6e297d0e399ef3768')
440275732Sjmg
441275732Sjmg		c = Crypto(CRYPTO_AES_ICM, key)
442275732Sjmg		enc = c.encrypt(pt, iv)
443275732Sjmg
444275732Sjmg		print 'enc:', enc.encode('hex')
445275732Sjmg		print ' ct:', ct.encode('hex')
446275732Sjmg
447275732Sjmg		assert ct == enc
448275732Sjmg
449275732Sjmg		dec = c.decrypt(ct, iv)
450275732Sjmg
451275732Sjmg		print 'dec:', dec.encode('hex')
452275732Sjmg		print ' pt:', pt.encode('hex')
453275732Sjmg
454275732Sjmg		assert pt == dec
455275732Sjmg	elif False:
456275732Sjmg		key = _spdechex('c939cc13397c1d37de6ae0e1cb7c423c')
457275732Sjmg		iv = _spdechex('6eba2716ec0bd6fa5cdef5e6d3a795bc')
458275732Sjmg		pt = _spdechex('ab3cabed693a32946055524052afe3c9cb49664f09fc8b7da824d924006b7496353b8c1657c5dec564d8f38d7432e1de35aae9d95590e66278d4acce883e51abaf94977fcd3679660109a92bf7b2973ccd547f065ec6cee4cb4a72a5e9f45e615d920d76cb34cba482467b3e21422a7242e7d931330c0fbf465c3a3a46fae943029fd899626dda542750a1eee253df323c6ef1573f1c8c156613e2ea0a6cdbf2ae9701020be2d6a83ecb7f3f9d8e0a3f')
459275732Sjmg		ct = _spdechex('f1f81f12e72e992dbdc304032705dc75dc3e4180eff8ee4819906af6aee876d5b00b7c36d282a445ce3620327be481e8e53a8e5a8e5ca9abfeb2281be88d12ffa8f46d958d8224738c1f7eea48bda03edbf9adeb900985f4fa25648b406d13a886c25e70cfdecdde0ad0f2991420eb48a61c64fd797237cf2798c2675b9bb744360b0a3f329ac53bbceb4e3e7456e6514f1a9d2f06c236c31d0f080b79c15dce1096357416602520daa098b17d1af427')
460275732Sjmg		c = Crypto(CRYPTO_AES_CBC, key)
461275732Sjmg
462275732Sjmg		enc = c.encrypt(pt, iv)
463275732Sjmg
464275732Sjmg		print 'enc:', enc.encode('hex')
465275732Sjmg		print ' ct:', ct.encode('hex')
466275732Sjmg
467275732Sjmg		assert ct == enc
468275732Sjmg
469275732Sjmg		dec = c.decrypt(ct, iv)
470275732Sjmg
471275732Sjmg		print 'dec:', dec.encode('hex')
472275732Sjmg		print ' pt:', pt.encode('hex')
473275732Sjmg
474275732Sjmg		assert pt == dec
475275732Sjmg	elif False:
476275732Sjmg		key = _spdechex('c939cc13397c1d37de6ae0e1cb7c423c')
477275732Sjmg		iv = _spdechex('b3d8cc017cbb89b39e0f67e2')
478275732Sjmg		pt = _spdechex('c3b3c41f113a31b73d9a5cd4321030')
479275732Sjmg		aad = _spdechex('24825602bd12a984e0092d3e448eda5f')
480275732Sjmg		ct = _spdechex('93fe7d9e9bfd10348a5606e5cafa7354')
481275732Sjmg		ct = _spdechex('93fe7d9e9bfd10348a5606e5cafa73')
482275732Sjmg		tag = _spdechex('0032a1dc85f1c9786925a2e71d8272dd')
483275732Sjmg		tag = _spdechex('8d11a0929cb3fbe1fef01a4a38d5f8ea')
484275732Sjmg
485275732Sjmg		c = Crypto(CRYPTO_AES_NIST_GCM_16, key,
486275732Sjmg		    mac=CRYPTO_AES_128_NIST_GMAC, mackey=key)
487275732Sjmg
488275732Sjmg		enc, enctag = c.encrypt(pt, iv, aad=aad)
489275732Sjmg
490275732Sjmg		print 'enc:', enc.encode('hex')
491275732Sjmg		print ' ct:', ct.encode('hex')
492275732Sjmg
493275732Sjmg		assert enc == ct
494275732Sjmg
495275732Sjmg		print 'etg:', enctag.encode('hex')
496275732Sjmg		print 'tag:', tag.encode('hex')
497275732Sjmg		assert enctag == tag
498275732Sjmg
499275732Sjmg		# Make sure we get EBADMSG
500275732Sjmg		#enctag = enctag[:-1] + 'a'
501275732Sjmg		dec, dectag = c.decrypt(ct, iv, aad=aad, tag=enctag)
502275732Sjmg
503275732Sjmg		print 'dec:', dec.encode('hex')
504275732Sjmg		print ' pt:', pt.encode('hex')
505275732Sjmg
506275732Sjmg		assert dec == pt
507275732Sjmg
508275732Sjmg		print 'dtg:', dectag.encode('hex')
509275732Sjmg		print 'tag:', tag.encode('hex')
510275732Sjmg
511275732Sjmg		assert dectag == tag
512275732Sjmg	elif False:
513275732Sjmg		key = _spdechex('c939cc13397c1d37de6ae0e1cb7c423c')
514275732Sjmg		iv = _spdechex('b3d8cc017cbb89b39e0f67e2')
515275732Sjmg		key = key + iv[:4]
516275732Sjmg		iv = iv[4:]
517275732Sjmg		pt = _spdechex('c3b3c41f113a31b73d9a5cd432103069')
518275732Sjmg		aad = _spdechex('24825602bd12a984e0092d3e448eda5f')
519275732Sjmg		ct = _spdechex('93fe7d9e9bfd10348a5606e5cafa7354')
520275732Sjmg		tag = _spdechex('0032a1dc85f1c9786925a2e71d8272dd')
521275732Sjmg
522275732Sjmg		c = Crypto(CRYPTO_AES_GCM_16, key, mac=CRYPTO_AES_128_GMAC, mackey=key)
523275732Sjmg
524275732Sjmg		enc, enctag = c.encrypt(pt, iv, aad=aad)
525275732Sjmg
526275732Sjmg		print 'enc:', enc.encode('hex')
527275732Sjmg		print ' ct:', ct.encode('hex')
528275732Sjmg
529275732Sjmg		assert enc == ct
530275732Sjmg
531275732Sjmg		print 'etg:', enctag.encode('hex')
532275732Sjmg		print 'tag:', tag.encode('hex')
533275732Sjmg		assert enctag == tag
534275732Sjmg	elif False:
535275732Sjmg		for i in xrange(100000):
536275732Sjmg			c = Crypto(CRYPTO_AES_XTS, '1bbfeadf539daedcae33ced497343f3ca1f2474ad932b903997d44707db41382'.decode('hex'))
537275732Sjmg			data = '52a42bca4e9425a25bbc8c8bf6129dec'.decode('hex')
538275732Sjmg			ct = '517e602becd066b65fa4f4f56ddfe240'.decode('hex')
539275732Sjmg			iv = _pack('QQ', 71, 0)
540275732Sjmg
541275732Sjmg			enc = c.encrypt(data, iv)
542275732Sjmg			assert enc == ct
543275732Sjmg	elif True:
544275732Sjmg		c = Crypto(CRYPTO_AES_XTS, '1bbfeadf539daedcae33ced497343f3ca1f2474ad932b903997d44707db41382'.decode('hex'))
545275732Sjmg		data = '52a42bca4e9425a25bbc8c8bf6129dec'.decode('hex')
546275732Sjmg		ct = '517e602becd066b65fa4f4f56ddfe240'.decode('hex')
547275732Sjmg		iv = _pack('QQ', 71, 0)
548275732Sjmg
549275732Sjmg		enc = c.encrypt(data, iv)
550275732Sjmg		assert enc == ct
551275732Sjmg
552275732Sjmg		dec = c.decrypt(enc, iv)
553275732Sjmg		assert dec == data
554275732Sjmg
555275732Sjmg		#c.perftest(COP_ENCRYPT, 192*1024, reps=30000)
556275732Sjmg
557275732Sjmg	else:
558275732Sjmg		key = '1bbfeadf539daedcae33ced497343f3ca1f2474ad932b903997d44707db41382'.decode('hex')
559275732Sjmg		print 'XTS %d testing:' % (len(key) * 8)
560275732Sjmg		c = Crypto(CRYPTO_AES_XTS, key)
561275732Sjmg		for i in [ 8192, 192*1024]:
562275732Sjmg			print 'block size: %d' % i
563275732Sjmg			c.perftest(COP_ENCRYPT, i)
564275732Sjmg			c.perftest(COP_DECRYPT, i)
565