xform_sha2.c revision 247061
1104476Ssam/*	$OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $	*/
2139825Simp/*-
3104476Ssam * The authors of this code are John Ioannidis (ji@tla.org),
4247061Spjd * Angelos D. Keromytis (kermit@csd.uch.gr),
5247061Spjd * Niels Provos (provos@physnet.uni-hamburg.de) and
6247061Spjd * Damien Miller (djm@mindrot.org).
7104476Ssam *
8104476Ssam * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
9104476Ssam * in November 1995.
10104476Ssam *
11104476Ssam * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
12104476Ssam * by Angelos D. Keromytis.
13104476Ssam *
14104476Ssam * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
15104476Ssam * and Niels Provos.
16104476Ssam *
17104476Ssam * Additional features in 1999 by Angelos D. Keromytis.
18104476Ssam *
19247061Spjd * AES XTS implementation in 2008 by Damien Miller
20247061Spjd *
21104476Ssam * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
22104476Ssam * Angelos D. Keromytis and Niels Provos.
23104476Ssam *
24104476Ssam * Copyright (C) 2001, Angelos D. Keromytis.
25104476Ssam *
26247061Spjd * Copyright (C) 2008, Damien Miller
27247061Spjd *
28104476Ssam * Permission to use, copy, and modify this software with or without fee
29104476Ssam * is hereby granted, provided that this entire notice is included in
30104476Ssam * all copies of any software which is or includes a copy or
31104476Ssam * modification of this software.
32104476Ssam * You may use this code under the GNU public license if you so wish. Please
33104476Ssam * contribute changes back to the authors under this freer than GPL license
34104476Ssam * so that we may further the use of strong encryption without limitations to
35104476Ssam * all.
36104476Ssam *
37104476Ssam * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
38104476Ssam * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
39104476Ssam * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
40104476Ssam * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
41104476Ssam * PURPOSE.
42104476Ssam */
43104476Ssam
44116191Sobrien#include <sys/cdefs.h>
45116191Sobrien__FBSDID("$FreeBSD: head/sys/opencrypto/xform.c 247061 2013-02-20 22:59:53Z pjd $");
46116191Sobrien
47104476Ssam#include <sys/param.h>
48104476Ssam#include <sys/systm.h>
49104476Ssam#include <sys/malloc.h>
50104476Ssam#include <sys/sysctl.h>
51104476Ssam#include <sys/errno.h>
52104476Ssam#include <sys/time.h>
53104476Ssam#include <sys/kernel.h>
54104476Ssam#include <machine/cpu.h>
55104476Ssam
56104476Ssam#include <crypto/blowfish/blowfish.h>
57104476Ssam#include <crypto/des/des.h>
58143423Sume#include <crypto/rijndael/rijndael.h>
59169425Sgnn#include <crypto/camellia/camellia.h>
60104476Ssam#include <crypto/sha1.h>
61104476Ssam
62104476Ssam#include <opencrypto/cast.h>
63104476Ssam#include <opencrypto/deflate.h>
64104476Ssam#include <opencrypto/rmd160.h>
65104476Ssam#include <opencrypto/skipjack.h>
66104476Ssam
67104476Ssam#include <sys/md5.h>
68104476Ssam
69104476Ssam#include <opencrypto/cryptodev.h>
70104476Ssam#include <opencrypto/xform.h>
71104476Ssam
72213068Spjdstatic	int null_setkey(u_int8_t **, u_int8_t *, int);
73104476Ssamstatic	int des1_setkey(u_int8_t **, u_int8_t *, int);
74104476Ssamstatic	int des3_setkey(u_int8_t **, u_int8_t *, int);
75104476Ssamstatic	int blf_setkey(u_int8_t **, u_int8_t *, int);
76104476Ssamstatic	int cast5_setkey(u_int8_t **, u_int8_t *, int);
77104476Ssamstatic	int skipjack_setkey(u_int8_t **, u_int8_t *, int);
78104476Ssamstatic	int rijndael128_setkey(u_int8_t **, u_int8_t *, int);
79213068Spjdstatic	int aes_xts_setkey(u_int8_t **, u_int8_t *, int);
80169425Sgnnstatic	int cml_setkey(u_int8_t **, u_int8_t *, int);
81213068Spjd
82213068Spjdstatic	void null_encrypt(caddr_t, u_int8_t *);
83104476Ssamstatic	void des1_encrypt(caddr_t, u_int8_t *);
84104476Ssamstatic	void des3_encrypt(caddr_t, u_int8_t *);
85104476Ssamstatic	void blf_encrypt(caddr_t, u_int8_t *);
86104476Ssamstatic	void cast5_encrypt(caddr_t, u_int8_t *);
87104476Ssamstatic	void skipjack_encrypt(caddr_t, u_int8_t *);
88104476Ssamstatic	void rijndael128_encrypt(caddr_t, u_int8_t *);
89213068Spjdstatic	void aes_xts_encrypt(caddr_t, u_int8_t *);
90169425Sgnnstatic	void cml_encrypt(caddr_t, u_int8_t *);
91213068Spjd
92213068Spjdstatic	void null_decrypt(caddr_t, u_int8_t *);
93104476Ssamstatic	void des1_decrypt(caddr_t, u_int8_t *);
94104476Ssamstatic	void des3_decrypt(caddr_t, u_int8_t *);
95104476Ssamstatic	void blf_decrypt(caddr_t, u_int8_t *);
96104476Ssamstatic	void cast5_decrypt(caddr_t, u_int8_t *);
97104476Ssamstatic	void skipjack_decrypt(caddr_t, u_int8_t *);
98104476Ssamstatic	void rijndael128_decrypt(caddr_t, u_int8_t *);
99213068Spjdstatic	void aes_xts_decrypt(caddr_t, u_int8_t *);
100169425Sgnnstatic	void cml_decrypt(caddr_t, u_int8_t *);
101213068Spjd
102213068Spjdstatic	void null_zerokey(u_int8_t **);
103104476Ssamstatic	void des1_zerokey(u_int8_t **);
104104476Ssamstatic	void des3_zerokey(u_int8_t **);
105104476Ssamstatic	void blf_zerokey(u_int8_t **);
106104476Ssamstatic	void cast5_zerokey(u_int8_t **);
107104476Ssamstatic	void skipjack_zerokey(u_int8_t **);
108104476Ssamstatic	void rijndael128_zerokey(u_int8_t **);
109213068Spjdstatic	void aes_xts_zerokey(u_int8_t **);
110169425Sgnnstatic	void cml_zerokey(u_int8_t **);
111104476Ssam
112213068Spjdstatic	void aes_xts_reinit(caddr_t, u_int8_t *);
113213068Spjd
114104476Ssamstatic	void null_init(void *);
115104476Ssamstatic	int null_update(void *, u_int8_t *, u_int16_t);
116104476Ssamstatic	void null_final(u_int8_t *, void *);
117104476Ssamstatic	int MD5Update_int(void *, u_int8_t *, u_int16_t);
118104476Ssamstatic	void SHA1Init_int(void *);
119104476Ssamstatic	int SHA1Update_int(void *, u_int8_t *, u_int16_t);
120104476Ssamstatic	void SHA1Final_int(u_int8_t *, void *);
121104476Ssamstatic	int RMD160Update_int(void *, u_int8_t *, u_int16_t);
122104476Ssamstatic	int SHA256Update_int(void *, u_int8_t *, u_int16_t);
123104476Ssamstatic	int SHA384Update_int(void *, u_int8_t *, u_int16_t);
124104476Ssamstatic	int SHA512Update_int(void *, u_int8_t *, u_int16_t);
125104476Ssam
126104476Ssamstatic	u_int32_t deflate_compress(u_int8_t *, u_int32_t, u_int8_t **);
127104476Ssamstatic	u_int32_t deflate_decompress(u_int8_t *, u_int32_t, u_int8_t **);
128104476Ssam
129104476SsamMALLOC_DEFINE(M_XDATA, "xform", "xform data buffers");
130104476Ssam
131104476Ssam/* Encryption instances */
132104476Ssamstruct enc_xform enc_xform_null = {
133104476Ssam	CRYPTO_NULL_CBC, "NULL",
134104476Ssam	/* NB: blocksize of 4 is to generate a properly aligned ESP header */
135159235Spjd	NULL_BLOCK_LEN, 0, 256, /* 2048 bits, max key */
136104476Ssam	null_encrypt,
137104476Ssam	null_decrypt,
138104476Ssam	null_setkey,
139104476Ssam	null_zerokey,
140213068Spjd	NULL
141104476Ssam};
142104476Ssam
143104476Ssamstruct enc_xform enc_xform_des = {
144104476Ssam	CRYPTO_DES_CBC, "DES",
145159235Spjd	DES_BLOCK_LEN, 8, 8,
146104476Ssam	des1_encrypt,
147104476Ssam	des1_decrypt,
148104476Ssam	des1_setkey,
149104476Ssam	des1_zerokey,
150213068Spjd	NULL
151104476Ssam};
152104476Ssam
153104476Ssamstruct enc_xform enc_xform_3des = {
154104476Ssam	CRYPTO_3DES_CBC, "3DES",
155159235Spjd	DES3_BLOCK_LEN, 24, 24,
156104476Ssam	des3_encrypt,
157104476Ssam	des3_decrypt,
158104476Ssam	des3_setkey,
159213068Spjd	des3_zerokey,
160213068Spjd	NULL
161104476Ssam};
162104476Ssam
163104476Ssamstruct enc_xform enc_xform_blf = {
164104476Ssam	CRYPTO_BLF_CBC, "Blowfish",
165159235Spjd	BLOWFISH_BLOCK_LEN, 5, 56 /* 448 bits, max key */,
166104476Ssam	blf_encrypt,
167104476Ssam	blf_decrypt,
168104476Ssam	blf_setkey,
169213068Spjd	blf_zerokey,
170213068Spjd	NULL
171104476Ssam};
172104476Ssam
173104476Ssamstruct enc_xform enc_xform_cast5 = {
174104476Ssam	CRYPTO_CAST_CBC, "CAST-128",
175159235Spjd	CAST128_BLOCK_LEN, 5, 16,
176104476Ssam	cast5_encrypt,
177104476Ssam	cast5_decrypt,
178104476Ssam	cast5_setkey,
179213068Spjd	cast5_zerokey,
180213068Spjd	NULL
181104476Ssam};
182104476Ssam
183104476Ssamstruct enc_xform enc_xform_skipjack = {
184104476Ssam	CRYPTO_SKIPJACK_CBC, "Skipjack",
185159235Spjd	SKIPJACK_BLOCK_LEN, 10, 10,
186104476Ssam	skipjack_encrypt,
187104476Ssam	skipjack_decrypt,
188104476Ssam	skipjack_setkey,
189213068Spjd	skipjack_zerokey,
190213068Spjd	NULL
191104476Ssam};
192104476Ssam
193104476Ssamstruct enc_xform enc_xform_rijndael128 = {
194104476Ssam	CRYPTO_RIJNDAEL128_CBC, "Rijndael-128/AES",
195159235Spjd	RIJNDAEL128_BLOCK_LEN, 8, 32,
196104476Ssam	rijndael128_encrypt,
197104476Ssam	rijndael128_decrypt,
198104476Ssam	rijndael128_setkey,
199104476Ssam	rijndael128_zerokey,
200213068Spjd	NULL
201104476Ssam};
202104476Ssam
203213068Spjdstruct enc_xform enc_xform_aes_xts = {
204213068Spjd	CRYPTO_AES_XTS, "AES-XTS",
205213068Spjd	RIJNDAEL128_BLOCK_LEN, 32, 64,
206213068Spjd	aes_xts_encrypt,
207213068Spjd	aes_xts_decrypt,
208213068Spjd	aes_xts_setkey,
209213068Spjd	aes_xts_zerokey,
210213068Spjd	aes_xts_reinit
211213068Spjd};
212213068Spjd
213104476Ssamstruct enc_xform enc_xform_arc4 = {
214104476Ssam	CRYPTO_ARC4, "ARC4",
215104476Ssam	1, 1, 32,
216104476Ssam	NULL,
217104476Ssam	NULL,
218104476Ssam	NULL,
219104476Ssam	NULL,
220213068Spjd	NULL
221104476Ssam};
222104476Ssam
223169425Sgnnstruct enc_xform enc_xform_camellia = {
224169425Sgnn	CRYPTO_CAMELLIA_CBC, "Camellia",
225169425Sgnn	CAMELLIA_BLOCK_LEN, 8, 32,
226169425Sgnn	cml_encrypt,
227169425Sgnn	cml_decrypt,
228169425Sgnn	cml_setkey,
229169425Sgnn	cml_zerokey,
230213068Spjd	NULL
231169425Sgnn};
232169425Sgnn
233104476Ssam/* Authentication instances */
234104476Ssamstruct auth_hash auth_hash_null = {
235104476Ssam	CRYPTO_NULL_HMAC, "NULL-HMAC",
236159235Spjd	0, NULL_HASH_LEN, NULL_HMAC_BLOCK_LEN, sizeof(int),	/* NB: context isn't used */
237104476Ssam	null_init, null_update, null_final
238104476Ssam};
239104476Ssam
240158703Spjdstruct auth_hash auth_hash_hmac_md5 = {
241104476Ssam	CRYPTO_MD5_HMAC, "HMAC-MD5",
242159235Spjd	16, MD5_HASH_LEN, MD5_HMAC_BLOCK_LEN, sizeof(MD5_CTX),
243104476Ssam	(void (*) (void *)) MD5Init, MD5Update_int,
244104476Ssam	(void (*) (u_int8_t *, void *)) MD5Final
245104476Ssam};
246104476Ssam
247158703Spjdstruct auth_hash auth_hash_hmac_sha1 = {
248104476Ssam	CRYPTO_SHA1_HMAC, "HMAC-SHA1",
249159235Spjd	20, SHA1_HASH_LEN, SHA1_HMAC_BLOCK_LEN, sizeof(SHA1_CTX),
250104476Ssam	SHA1Init_int, SHA1Update_int, SHA1Final_int
251104476Ssam};
252104476Ssam
253158703Spjdstruct auth_hash auth_hash_hmac_ripemd_160 = {
254104476Ssam	CRYPTO_RIPEMD160_HMAC, "HMAC-RIPEMD-160",
255159235Spjd	20, RIPEMD160_HASH_LEN, RIPEMD160_HMAC_BLOCK_LEN, sizeof(RMD160_CTX),
256104476Ssam	(void (*)(void *)) RMD160Init, RMD160Update_int,
257104476Ssam	(void (*)(u_int8_t *, void *)) RMD160Final
258104476Ssam};
259104476Ssam
260104476Ssamstruct auth_hash auth_hash_key_md5 = {
261213065Spjd	CRYPTO_MD5_KPDK, "Keyed MD5",
262159235Spjd	0, MD5_KPDK_HASH_LEN, 0, sizeof(MD5_CTX),
263104476Ssam	(void (*)(void *)) MD5Init, MD5Update_int,
264104476Ssam	(void (*)(u_int8_t *, void *)) MD5Final
265104476Ssam};
266104476Ssam
267104476Ssamstruct auth_hash auth_hash_key_sha1 = {
268104476Ssam	CRYPTO_SHA1_KPDK, "Keyed SHA1",
269159235Spjd	0, SHA1_KPDK_HASH_LEN, 0, sizeof(SHA1_CTX),
270104476Ssam	SHA1Init_int, SHA1Update_int, SHA1Final_int
271104476Ssam};
272104476Ssam
273104476Ssamstruct auth_hash auth_hash_hmac_sha2_256 = {
274158703Spjd	CRYPTO_SHA2_256_HMAC, "HMAC-SHA2-256",
275159235Spjd	32, SHA2_256_HASH_LEN, SHA2_256_HMAC_BLOCK_LEN, sizeof(SHA256_CTX),
276104476Ssam	(void (*)(void *)) SHA256_Init, SHA256Update_int,
277104476Ssam	(void (*)(u_int8_t *, void *)) SHA256_Final
278104476Ssam};
279104476Ssam
280104476Ssamstruct auth_hash auth_hash_hmac_sha2_384 = {
281158703Spjd	CRYPTO_SHA2_384_HMAC, "HMAC-SHA2-384",
282159235Spjd	48, SHA2_384_HASH_LEN, SHA2_384_HMAC_BLOCK_LEN, sizeof(SHA384_CTX),
283104476Ssam	(void (*)(void *)) SHA384_Init, SHA384Update_int,
284104476Ssam	(void (*)(u_int8_t *, void *)) SHA384_Final
285104476Ssam};
286104476Ssam
287104476Ssamstruct auth_hash auth_hash_hmac_sha2_512 = {
288158703Spjd	CRYPTO_SHA2_512_HMAC, "HMAC-SHA2-512",
289159235Spjd	64, SHA2_512_HASH_LEN, SHA2_512_HMAC_BLOCK_LEN, sizeof(SHA512_CTX),
290104476Ssam	(void (*)(void *)) SHA512_Init, SHA512Update_int,
291104476Ssam	(void (*)(u_int8_t *, void *)) SHA512_Final
292104476Ssam};
293104476Ssam
294104476Ssam/* Compression instance */
295104476Ssamstruct comp_algo comp_algo_deflate = {
296104476Ssam	CRYPTO_DEFLATE_COMP, "Deflate",
297104476Ssam	90, deflate_compress,
298104476Ssam	deflate_decompress
299104476Ssam};
300104476Ssam
301104476Ssam/*
302104476Ssam * Encryption wrapper routines.
303104476Ssam */
304104476Ssamstatic void
305104476Ssamnull_encrypt(caddr_t key, u_int8_t *blk)
306104476Ssam{
307104476Ssam}
308104476Ssamstatic void
309104476Ssamnull_decrypt(caddr_t key, u_int8_t *blk)
310104476Ssam{
311104476Ssam}
312104476Ssamstatic int
313104476Ssamnull_setkey(u_int8_t **sched, u_int8_t *key, int len)
314104476Ssam{
315104476Ssam	*sched = NULL;
316104476Ssam	return 0;
317104476Ssam}
318104476Ssamstatic void
319104476Ssamnull_zerokey(u_int8_t **sched)
320104476Ssam{
321104476Ssam	*sched = NULL;
322104476Ssam}
323104476Ssam
324104476Ssamstatic void
325104476Ssamdes1_encrypt(caddr_t key, u_int8_t *blk)
326104476Ssam{
327104476Ssam	des_cblock *cb = (des_cblock *) blk;
328104476Ssam	des_key_schedule *p = (des_key_schedule *) key;
329104476Ssam
330104476Ssam	des_ecb_encrypt(cb, cb, p[0], DES_ENCRYPT);
331104476Ssam}
332104476Ssam
333104476Ssamstatic void
334104476Ssamdes1_decrypt(caddr_t key, u_int8_t *blk)
335104476Ssam{
336104476Ssam	des_cblock *cb = (des_cblock *) blk;
337104476Ssam	des_key_schedule *p = (des_key_schedule *) key;
338104476Ssam
339104476Ssam	des_ecb_encrypt(cb, cb, p[0], DES_DECRYPT);
340104476Ssam}
341104476Ssam
342104476Ssamstatic int
343104476Ssamdes1_setkey(u_int8_t **sched, u_int8_t *key, int len)
344104476Ssam{
345104476Ssam	des_key_schedule *p;
346104476Ssam	int err;
347104476Ssam
348184205Sdes	p = malloc(sizeof (des_key_schedule),
349104476Ssam		M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
350104476Ssam	if (p != NULL) {
351104476Ssam		des_set_key((des_cblock *) key, p[0]);
352104476Ssam		err = 0;
353104476Ssam	} else
354104476Ssam		err = ENOMEM;
355104476Ssam	*sched = (u_int8_t *) p;
356104476Ssam	return err;
357104476Ssam}
358104476Ssam
359104476Ssamstatic void
360104476Ssamdes1_zerokey(u_int8_t **sched)
361104476Ssam{
362104476Ssam	bzero(*sched, sizeof (des_key_schedule));
363184205Sdes	free(*sched, M_CRYPTO_DATA);
364104476Ssam	*sched = NULL;
365104476Ssam}
366104476Ssam
367104476Ssamstatic void
368104476Ssamdes3_encrypt(caddr_t key, u_int8_t *blk)
369104476Ssam{
370104476Ssam	des_cblock *cb = (des_cblock *) blk;
371104476Ssam	des_key_schedule *p = (des_key_schedule *) key;
372104476Ssam
373104476Ssam	des_ecb3_encrypt(cb, cb, p[0], p[1], p[2], DES_ENCRYPT);
374104476Ssam}
375104476Ssam
376104476Ssamstatic void
377104476Ssamdes3_decrypt(caddr_t key, u_int8_t *blk)
378104476Ssam{
379104476Ssam	des_cblock *cb = (des_cblock *) blk;
380104476Ssam	des_key_schedule *p = (des_key_schedule *) key;
381104476Ssam
382104476Ssam	des_ecb3_encrypt(cb, cb, p[0], p[1], p[2], DES_DECRYPT);
383104476Ssam}
384104476Ssam
385104476Ssamstatic int
386104476Ssamdes3_setkey(u_int8_t **sched, u_int8_t *key, int len)
387104476Ssam{
388104476Ssam	des_key_schedule *p;
389104476Ssam	int err;
390104476Ssam
391184205Sdes	p = malloc(3*sizeof (des_key_schedule),
392104476Ssam		M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
393104476Ssam	if (p != NULL) {
394104476Ssam		des_set_key((des_cblock *)(key +  0), p[0]);
395104476Ssam		des_set_key((des_cblock *)(key +  8), p[1]);
396104476Ssam		des_set_key((des_cblock *)(key + 16), p[2]);
397104476Ssam		err = 0;
398104476Ssam	} else
399104476Ssam		err = ENOMEM;
400104476Ssam	*sched = (u_int8_t *) p;
401104476Ssam	return err;
402104476Ssam}
403104476Ssam
404104476Ssamstatic void
405104476Ssamdes3_zerokey(u_int8_t **sched)
406104476Ssam{
407104476Ssam	bzero(*sched, 3*sizeof (des_key_schedule));
408184205Sdes	free(*sched, M_CRYPTO_DATA);
409104476Ssam	*sched = NULL;
410104476Ssam}
411104476Ssam
412104476Ssamstatic void
413104476Ssamblf_encrypt(caddr_t key, u_int8_t *blk)
414104476Ssam{
415104476Ssam	BF_LONG t[2];
416104476Ssam
417104476Ssam	memcpy(t, blk, sizeof (t));
418104476Ssam	t[0] = ntohl(t[0]);
419104476Ssam	t[1] = ntohl(t[1]);
420104476Ssam	/* NB: BF_encrypt expects the block in host order! */
421104476Ssam	BF_encrypt(t, (BF_KEY *) key);
422104476Ssam	t[0] = htonl(t[0]);
423104476Ssam	t[1] = htonl(t[1]);
424104476Ssam	memcpy(blk, t, sizeof (t));
425104476Ssam}
426104476Ssam
427104476Ssamstatic void
428104476Ssamblf_decrypt(caddr_t key, u_int8_t *blk)
429104476Ssam{
430104476Ssam	BF_LONG t[2];
431104476Ssam
432104476Ssam	memcpy(t, blk, sizeof (t));
433104476Ssam	t[0] = ntohl(t[0]);
434104476Ssam	t[1] = ntohl(t[1]);
435104476Ssam	/* NB: BF_decrypt expects the block in host order! */
436104476Ssam	BF_decrypt(t, (BF_KEY *) key);
437104476Ssam	t[0] = htonl(t[0]);
438104476Ssam	t[1] = htonl(t[1]);
439104476Ssam	memcpy(blk, t, sizeof (t));
440104476Ssam}
441104476Ssam
442104476Ssamstatic int
443104476Ssamblf_setkey(u_int8_t **sched, u_int8_t *key, int len)
444104476Ssam{
445104476Ssam	int err;
446104476Ssam
447184205Sdes	*sched = malloc(sizeof(BF_KEY),
448104476Ssam		M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
449104476Ssam	if (*sched != NULL) {
450104476Ssam		BF_set_key((BF_KEY *) *sched, len, key);
451104476Ssam		err = 0;
452104476Ssam	} else
453104476Ssam		err = ENOMEM;
454104476Ssam	return err;
455104476Ssam}
456104476Ssam
457104476Ssamstatic void
458104476Ssamblf_zerokey(u_int8_t **sched)
459104476Ssam{
460104476Ssam	bzero(*sched, sizeof(BF_KEY));
461184205Sdes	free(*sched, M_CRYPTO_DATA);
462104476Ssam	*sched = NULL;
463104476Ssam}
464104476Ssam
465104476Ssamstatic void
466104476Ssamcast5_encrypt(caddr_t key, u_int8_t *blk)
467104476Ssam{
468104476Ssam	cast_encrypt((cast_key *) key, blk, blk);
469104476Ssam}
470104476Ssam
471104476Ssamstatic void
472104476Ssamcast5_decrypt(caddr_t key, u_int8_t *blk)
473104476Ssam{
474104476Ssam	cast_decrypt((cast_key *) key, blk, blk);
475104476Ssam}
476104476Ssam
477104476Ssamstatic int
478104476Ssamcast5_setkey(u_int8_t **sched, u_int8_t *key, int len)
479104476Ssam{
480104476Ssam	int err;
481104476Ssam
482184205Sdes	*sched = malloc(sizeof(cast_key), M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
483104476Ssam	if (*sched != NULL) {
484104476Ssam		cast_setkey((cast_key *)*sched, key, len);
485104476Ssam		err = 0;
486104476Ssam	} else
487104476Ssam		err = ENOMEM;
488104476Ssam	return err;
489104476Ssam}
490104476Ssam
491104476Ssamstatic void
492104476Ssamcast5_zerokey(u_int8_t **sched)
493104476Ssam{
494104476Ssam	bzero(*sched, sizeof(cast_key));
495184205Sdes	free(*sched, M_CRYPTO_DATA);
496104476Ssam	*sched = NULL;
497104476Ssam}
498104476Ssam
499104476Ssamstatic void
500104476Ssamskipjack_encrypt(caddr_t key, u_int8_t *blk)
501104476Ssam{
502104476Ssam	skipjack_forwards(blk, blk, (u_int8_t **) key);
503104476Ssam}
504104476Ssam
505104476Ssamstatic void
506104476Ssamskipjack_decrypt(caddr_t key, u_int8_t *blk)
507104476Ssam{
508104476Ssam	skipjack_backwards(blk, blk, (u_int8_t **) key);
509104476Ssam}
510104476Ssam
511104476Ssamstatic int
512104476Ssamskipjack_setkey(u_int8_t **sched, u_int8_t *key, int len)
513104476Ssam{
514104476Ssam	int err;
515104476Ssam
516104476Ssam	/* NB: allocate all the memory that's needed at once */
517184205Sdes	*sched = malloc(10 * (sizeof(u_int8_t *) + 0x100),
518104476Ssam		M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
519104476Ssam	if (*sched != NULL) {
520104476Ssam		u_int8_t** key_tables = (u_int8_t**) *sched;
521104476Ssam		u_int8_t* table = (u_int8_t*) &key_tables[10];
522104476Ssam		int k;
523104476Ssam
524104476Ssam		for (k = 0; k < 10; k++) {
525104476Ssam			key_tables[k] = table;
526104476Ssam			table += 0x100;
527104476Ssam		}
528104476Ssam		subkey_table_gen(key, (u_int8_t **) *sched);
529104476Ssam		err = 0;
530104476Ssam	} else
531104476Ssam		err = ENOMEM;
532104476Ssam	return err;
533104476Ssam}
534104476Ssam
535104476Ssamstatic void
536104476Ssamskipjack_zerokey(u_int8_t **sched)
537104476Ssam{
538104476Ssam	bzero(*sched, 10 * (sizeof(u_int8_t *) + 0x100));
539184205Sdes	free(*sched, M_CRYPTO_DATA);
540104476Ssam	*sched = NULL;
541104476Ssam}
542104476Ssam
543104476Ssamstatic void
544104476Ssamrijndael128_encrypt(caddr_t key, u_int8_t *blk)
545104476Ssam{
546104476Ssam	rijndael_encrypt((rijndael_ctx *) key, (u_char *) blk, (u_char *) blk);
547104476Ssam}
548104476Ssam
549104476Ssamstatic void
550104476Ssamrijndael128_decrypt(caddr_t key, u_int8_t *blk)
551104476Ssam{
552143408Sume	rijndael_decrypt(((rijndael_ctx *) key), (u_char *) blk,
553104476Ssam	    (u_char *) blk);
554104476Ssam}
555104476Ssam
556104476Ssamstatic int
557104476Ssamrijndael128_setkey(u_int8_t **sched, u_int8_t *key, int len)
558104476Ssam{
559104476Ssam	int err;
560104476Ssam
561149143Spjd	if (len != 16 && len != 24 && len != 32)
562149143Spjd		return (EINVAL);
563184205Sdes	*sched = malloc(sizeof(rijndael_ctx), M_CRYPTO_DATA,
564104476Ssam	    M_NOWAIT|M_ZERO);
565104476Ssam	if (*sched != NULL) {
566143408Sume		rijndael_set_key((rijndael_ctx *) *sched, (u_char *) key,
567143408Sume		    len * 8);
568104476Ssam		err = 0;
569104476Ssam	} else
570104476Ssam		err = ENOMEM;
571104476Ssam	return err;
572104476Ssam}
573104476Ssam
574104476Ssamstatic void
575104476Ssamrijndael128_zerokey(u_int8_t **sched)
576104476Ssam{
577143408Sume	bzero(*sched, sizeof(rijndael_ctx));
578184205Sdes	free(*sched, M_CRYPTO_DATA);
579104476Ssam	*sched = NULL;
580104476Ssam}
581104476Ssam
582213068Spjd#define	AES_XTS_BLOCKSIZE	16
583213068Spjd#define	AES_XTS_IVSIZE		8
584213068Spjd#define	AES_XTS_ALPHA		0x87	/* GF(2^128) generator polynomial */
585213068Spjd
586213068Spjdstruct aes_xts_ctx {
587213068Spjd	rijndael_ctx key1;
588213068Spjd	rijndael_ctx key2;
589213068Spjd	u_int8_t tweak[AES_XTS_BLOCKSIZE];
590213068Spjd};
591213068Spjd
592213068Spjdvoid
593213068Spjdaes_xts_reinit(caddr_t key, u_int8_t *iv)
594213068Spjd{
595213068Spjd	struct aes_xts_ctx *ctx = (struct aes_xts_ctx *)key;
596213068Spjd	u_int64_t blocknum;
597213068Spjd	u_int i;
598213068Spjd
599213068Spjd	/*
600213068Spjd	 * Prepare tweak as E_k2(IV). IV is specified as LE representation
601213068Spjd	 * of a 64-bit block number which we allow to be passed in directly.
602213068Spjd	 */
603213068Spjd	bcopy(iv, &blocknum, AES_XTS_IVSIZE);
604213068Spjd	for (i = 0; i < AES_XTS_IVSIZE; i++) {
605213068Spjd		ctx->tweak[i] = blocknum & 0xff;
606213068Spjd		blocknum >>= 8;
607213068Spjd	}
608213068Spjd	/* Last 64 bits of IV are always zero */
609213068Spjd	bzero(ctx->tweak + AES_XTS_IVSIZE, AES_XTS_IVSIZE);
610213068Spjd
611213068Spjd	rijndael_encrypt(&ctx->key2, ctx->tweak, ctx->tweak);
612213068Spjd}
613213068Spjd
614169425Sgnnstatic void
615213068Spjdaes_xts_crypt(struct aes_xts_ctx *ctx, u_int8_t *data, u_int do_encrypt)
616213068Spjd{
617213068Spjd	u_int8_t block[AES_XTS_BLOCKSIZE];
618213068Spjd	u_int i, carry_in, carry_out;
619213068Spjd
620213068Spjd	for (i = 0; i < AES_XTS_BLOCKSIZE; i++)
621213068Spjd		block[i] = data[i] ^ ctx->tweak[i];
622213068Spjd
623213068Spjd	if (do_encrypt)
624213068Spjd		rijndael_encrypt(&ctx->key1, block, data);
625213068Spjd	else
626213068Spjd		rijndael_decrypt(&ctx->key1, block, data);
627213068Spjd
628213068Spjd	for (i = 0; i < AES_XTS_BLOCKSIZE; i++)
629213068Spjd		data[i] ^= ctx->tweak[i];
630213068Spjd
631213068Spjd	/* Exponentiate tweak */
632213068Spjd	carry_in = 0;
633213068Spjd	for (i = 0; i < AES_XTS_BLOCKSIZE; i++) {
634213068Spjd		carry_out = ctx->tweak[i] & 0x80;
635213068Spjd		ctx->tweak[i] = (ctx->tweak[i] << 1) | (carry_in ? 1 : 0);
636213068Spjd		carry_in = carry_out;
637213068Spjd	}
638213068Spjd	if (carry_in)
639213068Spjd		ctx->tweak[0] ^= AES_XTS_ALPHA;
640213068Spjd	bzero(block, sizeof(block));
641213068Spjd}
642213068Spjd
643213068Spjdvoid
644213068Spjdaes_xts_encrypt(caddr_t key, u_int8_t *data)
645213068Spjd{
646213068Spjd	aes_xts_crypt((struct aes_xts_ctx *)key, data, 1);
647213068Spjd}
648213068Spjd
649213068Spjdvoid
650213068Spjdaes_xts_decrypt(caddr_t key, u_int8_t *data)
651213068Spjd{
652213068Spjd	aes_xts_crypt((struct aes_xts_ctx *)key, data, 0);
653213068Spjd}
654213068Spjd
655213068Spjdint
656213068Spjdaes_xts_setkey(u_int8_t **sched, u_int8_t *key, int len)
657213068Spjd{
658213068Spjd	struct aes_xts_ctx *ctx;
659213068Spjd
660213068Spjd	if (len != 32 && len != 64)
661213068Spjd		return EINVAL;
662213068Spjd
663213068Spjd	*sched = malloc(sizeof(struct aes_xts_ctx), M_CRYPTO_DATA,
664213068Spjd	    M_NOWAIT | M_ZERO);
665213068Spjd	if (*sched == NULL)
666213068Spjd		return ENOMEM;
667213068Spjd	ctx = (struct aes_xts_ctx *)*sched;
668213068Spjd
669213068Spjd	rijndael_set_key(&ctx->key1, key, len * 4);
670213068Spjd	rijndael_set_key(&ctx->key2, key + (len / 2), len * 4);
671213068Spjd
672213068Spjd	return 0;
673213068Spjd}
674213068Spjd
675213068Spjdvoid
676213068Spjdaes_xts_zerokey(u_int8_t **sched)
677213068Spjd{
678213068Spjd	bzero(*sched, sizeof(struct aes_xts_ctx));
679213068Spjd	free(*sched, M_CRYPTO_DATA);
680213068Spjd	*sched = NULL;
681213068Spjd}
682213068Spjd
683213068Spjdstatic void
684169425Sgnncml_encrypt(caddr_t key, u_int8_t *blk)
685169425Sgnn{
686169425Sgnn	camellia_encrypt((camellia_ctx *) key, (u_char *) blk, (u_char *) blk);
687169425Sgnn}
688169425Sgnn
689169425Sgnnstatic void
690169425Sgnncml_decrypt(caddr_t key, u_int8_t *blk)
691169425Sgnn{
692169425Sgnn	camellia_decrypt(((camellia_ctx *) key), (u_char *) blk,
693169425Sgnn	    (u_char *) blk);
694169425Sgnn}
695169425Sgnn
696169425Sgnnstatic int
697169425Sgnncml_setkey(u_int8_t **sched, u_int8_t *key, int len)
698169425Sgnn{
699169425Sgnn	int err;
700169425Sgnn
701169425Sgnn	if (len != 16 && len != 24 && len != 32)
702169425Sgnn		return (EINVAL);
703184205Sdes	*sched = malloc(sizeof(camellia_ctx), M_CRYPTO_DATA,
704169425Sgnn	    M_NOWAIT|M_ZERO);
705169425Sgnn	if (*sched != NULL) {
706169425Sgnn		camellia_set_key((camellia_ctx *) *sched, (u_char *) key,
707169425Sgnn		    len * 8);
708169425Sgnn		err = 0;
709169425Sgnn	} else
710169425Sgnn		err = ENOMEM;
711169425Sgnn	return err;
712169425Sgnn}
713169425Sgnn
714169425Sgnnstatic void
715169425Sgnncml_zerokey(u_int8_t **sched)
716169425Sgnn{
717169425Sgnn	bzero(*sched, sizeof(camellia_ctx));
718184205Sdes	free(*sched, M_CRYPTO_DATA);
719169425Sgnn	*sched = NULL;
720169425Sgnn}
721169425Sgnn
722104476Ssam/*
723104476Ssam * And now for auth.
724104476Ssam */
725104476Ssam
726104476Ssamstatic void
727104476Ssamnull_init(void *ctx)
728104476Ssam{
729104476Ssam}
730104476Ssam
731104476Ssamstatic int
732104476Ssamnull_update(void *ctx, u_int8_t *buf, u_int16_t len)
733104476Ssam{
734104476Ssam	return 0;
735104476Ssam}
736104476Ssam
737104476Ssamstatic void
738104476Ssamnull_final(u_int8_t *buf, void *ctx)
739104476Ssam{
740104476Ssam	if (buf != (u_int8_t *) 0)
741104476Ssam		bzero(buf, 12);
742104476Ssam}
743104476Ssam
744104476Ssamstatic int
745104476SsamRMD160Update_int(void *ctx, u_int8_t *buf, u_int16_t len)
746104476Ssam{
747104476Ssam	RMD160Update(ctx, buf, len);
748104476Ssam	return 0;
749104476Ssam}
750104476Ssam
751104476Ssamstatic int
752104476SsamMD5Update_int(void *ctx, u_int8_t *buf, u_int16_t len)
753104476Ssam{
754104476Ssam	MD5Update(ctx, buf, len);
755104476Ssam	return 0;
756104476Ssam}
757104476Ssam
758104476Ssamstatic void
759104476SsamSHA1Init_int(void *ctx)
760104476Ssam{
761104476Ssam	SHA1Init(ctx);
762104476Ssam}
763104476Ssam
764104476Ssamstatic int
765104476SsamSHA1Update_int(void *ctx, u_int8_t *buf, u_int16_t len)
766104476Ssam{
767104476Ssam	SHA1Update(ctx, buf, len);
768104476Ssam	return 0;
769104476Ssam}
770104476Ssam
771104476Ssamstatic void
772104476SsamSHA1Final_int(u_int8_t *blk, void *ctx)
773104476Ssam{
774104476Ssam	SHA1Final(blk, ctx);
775104476Ssam}
776104476Ssam
777104476Ssamstatic int
778104476SsamSHA256Update_int(void *ctx, u_int8_t *buf, u_int16_t len)
779104476Ssam{
780104476Ssam	SHA256_Update(ctx, buf, len);
781104476Ssam	return 0;
782104476Ssam}
783104476Ssam
784104476Ssamstatic int
785104476SsamSHA384Update_int(void *ctx, u_int8_t *buf, u_int16_t len)
786104476Ssam{
787104476Ssam	SHA384_Update(ctx, buf, len);
788104476Ssam	return 0;
789104476Ssam}
790104476Ssam
791104476Ssamstatic int
792104476SsamSHA512Update_int(void *ctx, u_int8_t *buf, u_int16_t len)
793104476Ssam{
794104476Ssam	SHA512_Update(ctx, buf, len);
795104476Ssam	return 0;
796104476Ssam}
797104476Ssam
798104476Ssam/*
799104476Ssam * And compression
800104476Ssam */
801104476Ssam
802104476Ssamstatic u_int32_t
803104476Ssamdeflate_compress(data, size, out)
804104476Ssam	u_int8_t *data;
805104476Ssam	u_int32_t size;
806104476Ssam	u_int8_t **out;
807104476Ssam{
808104476Ssam	return deflate_global(data, size, 0, out);
809104476Ssam}
810104476Ssam
811104476Ssamstatic u_int32_t
812104476Ssamdeflate_decompress(data, size, out)
813104476Ssam	u_int8_t *data;
814104476Ssam	u_int32_t size;
815104476Ssam	u_int8_t **out;
816104476Ssam{
817104476Ssam	return deflate_global(data, size, 1, out);
818104476Ssam}
819