xref: /OK3568_Linux_fs/kernel/arch/x86/crypto/des3_ede_glue.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Glue Code for assembler optimized version of 3DES
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright © 2014 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by:
8*4882a593Smuzhiyun  *   Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
9*4882a593Smuzhiyun  * CTR part based on code (crypto/ctr.c) by:
10*4882a593Smuzhiyun  *   (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com>
11*4882a593Smuzhiyun  */
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include <crypto/algapi.h>
14*4882a593Smuzhiyun #include <crypto/des.h>
15*4882a593Smuzhiyun #include <crypto/internal/skcipher.h>
16*4882a593Smuzhiyun #include <linux/crypto.h>
17*4882a593Smuzhiyun #include <linux/init.h>
18*4882a593Smuzhiyun #include <linux/module.h>
19*4882a593Smuzhiyun #include <linux/types.h>
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun struct des3_ede_x86_ctx {
22*4882a593Smuzhiyun 	struct des3_ede_ctx enc;
23*4882a593Smuzhiyun 	struct des3_ede_ctx dec;
24*4882a593Smuzhiyun };
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun /* regular block cipher functions */
27*4882a593Smuzhiyun asmlinkage void des3_ede_x86_64_crypt_blk(const u32 *expkey, u8 *dst,
28*4882a593Smuzhiyun 					  const u8 *src);
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun /* 3-way parallel cipher functions */
31*4882a593Smuzhiyun asmlinkage void des3_ede_x86_64_crypt_blk_3way(const u32 *expkey, u8 *dst,
32*4882a593Smuzhiyun 					       const u8 *src);
33*4882a593Smuzhiyun 
des3_ede_enc_blk(struct des3_ede_x86_ctx * ctx,u8 * dst,const u8 * src)34*4882a593Smuzhiyun static inline void des3_ede_enc_blk(struct des3_ede_x86_ctx *ctx, u8 *dst,
35*4882a593Smuzhiyun 				    const u8 *src)
36*4882a593Smuzhiyun {
37*4882a593Smuzhiyun 	u32 *enc_ctx = ctx->enc.expkey;
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun 	des3_ede_x86_64_crypt_blk(enc_ctx, dst, src);
40*4882a593Smuzhiyun }
41*4882a593Smuzhiyun 
des3_ede_dec_blk(struct des3_ede_x86_ctx * ctx,u8 * dst,const u8 * src)42*4882a593Smuzhiyun static inline void des3_ede_dec_blk(struct des3_ede_x86_ctx *ctx, u8 *dst,
43*4882a593Smuzhiyun 				    const u8 *src)
44*4882a593Smuzhiyun {
45*4882a593Smuzhiyun 	u32 *dec_ctx = ctx->dec.expkey;
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun 	des3_ede_x86_64_crypt_blk(dec_ctx, dst, src);
48*4882a593Smuzhiyun }
49*4882a593Smuzhiyun 
des3_ede_enc_blk_3way(struct des3_ede_x86_ctx * ctx,u8 * dst,const u8 * src)50*4882a593Smuzhiyun static inline void des3_ede_enc_blk_3way(struct des3_ede_x86_ctx *ctx, u8 *dst,
51*4882a593Smuzhiyun 					 const u8 *src)
52*4882a593Smuzhiyun {
53*4882a593Smuzhiyun 	u32 *enc_ctx = ctx->enc.expkey;
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 	des3_ede_x86_64_crypt_blk_3way(enc_ctx, dst, src);
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun 
des3_ede_dec_blk_3way(struct des3_ede_x86_ctx * ctx,u8 * dst,const u8 * src)58*4882a593Smuzhiyun static inline void des3_ede_dec_blk_3way(struct des3_ede_x86_ctx *ctx, u8 *dst,
59*4882a593Smuzhiyun 					 const u8 *src)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun 	u32 *dec_ctx = ctx->dec.expkey;
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun 	des3_ede_x86_64_crypt_blk_3way(dec_ctx, dst, src);
64*4882a593Smuzhiyun }
65*4882a593Smuzhiyun 
des3_ede_x86_encrypt(struct crypto_tfm * tfm,u8 * dst,const u8 * src)66*4882a593Smuzhiyun static void des3_ede_x86_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun 	des3_ede_enc_blk(crypto_tfm_ctx(tfm), dst, src);
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun 
des3_ede_x86_decrypt(struct crypto_tfm * tfm,u8 * dst,const u8 * src)71*4882a593Smuzhiyun static void des3_ede_x86_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun 	des3_ede_dec_blk(crypto_tfm_ctx(tfm), dst, src);
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun 
ecb_crypt(struct skcipher_request * req,const u32 * expkey)76*4882a593Smuzhiyun static int ecb_crypt(struct skcipher_request *req, const u32 *expkey)
77*4882a593Smuzhiyun {
78*4882a593Smuzhiyun 	const unsigned int bsize = DES3_EDE_BLOCK_SIZE;
79*4882a593Smuzhiyun 	struct skcipher_walk walk;
80*4882a593Smuzhiyun 	unsigned int nbytes;
81*4882a593Smuzhiyun 	int err;
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	err = skcipher_walk_virt(&walk, req, false);
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	while ((nbytes = walk.nbytes)) {
86*4882a593Smuzhiyun 		u8 *wsrc = walk.src.virt.addr;
87*4882a593Smuzhiyun 		u8 *wdst = walk.dst.virt.addr;
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun 		/* Process four block batch */
90*4882a593Smuzhiyun 		if (nbytes >= bsize * 3) {
91*4882a593Smuzhiyun 			do {
92*4882a593Smuzhiyun 				des3_ede_x86_64_crypt_blk_3way(expkey, wdst,
93*4882a593Smuzhiyun 							       wsrc);
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 				wsrc += bsize * 3;
96*4882a593Smuzhiyun 				wdst += bsize * 3;
97*4882a593Smuzhiyun 				nbytes -= bsize * 3;
98*4882a593Smuzhiyun 			} while (nbytes >= bsize * 3);
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 			if (nbytes < bsize)
101*4882a593Smuzhiyun 				goto done;
102*4882a593Smuzhiyun 		}
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 		/* Handle leftovers */
105*4882a593Smuzhiyun 		do {
106*4882a593Smuzhiyun 			des3_ede_x86_64_crypt_blk(expkey, wdst, wsrc);
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 			wsrc += bsize;
109*4882a593Smuzhiyun 			wdst += bsize;
110*4882a593Smuzhiyun 			nbytes -= bsize;
111*4882a593Smuzhiyun 		} while (nbytes >= bsize);
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun done:
114*4882a593Smuzhiyun 		err = skcipher_walk_done(&walk, nbytes);
115*4882a593Smuzhiyun 	}
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 	return err;
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun 
ecb_encrypt(struct skcipher_request * req)120*4882a593Smuzhiyun static int ecb_encrypt(struct skcipher_request *req)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
123*4882a593Smuzhiyun 	struct des3_ede_x86_ctx *ctx = crypto_skcipher_ctx(tfm);
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	return ecb_crypt(req, ctx->enc.expkey);
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun 
ecb_decrypt(struct skcipher_request * req)128*4882a593Smuzhiyun static int ecb_decrypt(struct skcipher_request *req)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
131*4882a593Smuzhiyun 	struct des3_ede_x86_ctx *ctx = crypto_skcipher_ctx(tfm);
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	return ecb_crypt(req, ctx->dec.expkey);
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun 
__cbc_encrypt(struct des3_ede_x86_ctx * ctx,struct skcipher_walk * walk)136*4882a593Smuzhiyun static unsigned int __cbc_encrypt(struct des3_ede_x86_ctx *ctx,
137*4882a593Smuzhiyun 				  struct skcipher_walk *walk)
138*4882a593Smuzhiyun {
139*4882a593Smuzhiyun 	unsigned int bsize = DES3_EDE_BLOCK_SIZE;
140*4882a593Smuzhiyun 	unsigned int nbytes = walk->nbytes;
141*4882a593Smuzhiyun 	u64 *src = (u64 *)walk->src.virt.addr;
142*4882a593Smuzhiyun 	u64 *dst = (u64 *)walk->dst.virt.addr;
143*4882a593Smuzhiyun 	u64 *iv = (u64 *)walk->iv;
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	do {
146*4882a593Smuzhiyun 		*dst = *src ^ *iv;
147*4882a593Smuzhiyun 		des3_ede_enc_blk(ctx, (u8 *)dst, (u8 *)dst);
148*4882a593Smuzhiyun 		iv = dst;
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 		src += 1;
151*4882a593Smuzhiyun 		dst += 1;
152*4882a593Smuzhiyun 		nbytes -= bsize;
153*4882a593Smuzhiyun 	} while (nbytes >= bsize);
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	*(u64 *)walk->iv = *iv;
156*4882a593Smuzhiyun 	return nbytes;
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun 
cbc_encrypt(struct skcipher_request * req)159*4882a593Smuzhiyun static int cbc_encrypt(struct skcipher_request *req)
160*4882a593Smuzhiyun {
161*4882a593Smuzhiyun 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
162*4882a593Smuzhiyun 	struct des3_ede_x86_ctx *ctx = crypto_skcipher_ctx(tfm);
163*4882a593Smuzhiyun 	struct skcipher_walk walk;
164*4882a593Smuzhiyun 	unsigned int nbytes;
165*4882a593Smuzhiyun 	int err;
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	err = skcipher_walk_virt(&walk, req, false);
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	while ((nbytes = walk.nbytes)) {
170*4882a593Smuzhiyun 		nbytes = __cbc_encrypt(ctx, &walk);
171*4882a593Smuzhiyun 		err = skcipher_walk_done(&walk, nbytes);
172*4882a593Smuzhiyun 	}
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun 	return err;
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun 
__cbc_decrypt(struct des3_ede_x86_ctx * ctx,struct skcipher_walk * walk)177*4882a593Smuzhiyun static unsigned int __cbc_decrypt(struct des3_ede_x86_ctx *ctx,
178*4882a593Smuzhiyun 				  struct skcipher_walk *walk)
179*4882a593Smuzhiyun {
180*4882a593Smuzhiyun 	unsigned int bsize = DES3_EDE_BLOCK_SIZE;
181*4882a593Smuzhiyun 	unsigned int nbytes = walk->nbytes;
182*4882a593Smuzhiyun 	u64 *src = (u64 *)walk->src.virt.addr;
183*4882a593Smuzhiyun 	u64 *dst = (u64 *)walk->dst.virt.addr;
184*4882a593Smuzhiyun 	u64 ivs[3 - 1];
185*4882a593Smuzhiyun 	u64 last_iv;
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 	/* Start of the last block. */
188*4882a593Smuzhiyun 	src += nbytes / bsize - 1;
189*4882a593Smuzhiyun 	dst += nbytes / bsize - 1;
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	last_iv = *src;
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 	/* Process four block batch */
194*4882a593Smuzhiyun 	if (nbytes >= bsize * 3) {
195*4882a593Smuzhiyun 		do {
196*4882a593Smuzhiyun 			nbytes -= bsize * 3 - bsize;
197*4882a593Smuzhiyun 			src -= 3 - 1;
198*4882a593Smuzhiyun 			dst -= 3 - 1;
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 			ivs[0] = src[0];
201*4882a593Smuzhiyun 			ivs[1] = src[1];
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 			des3_ede_dec_blk_3way(ctx, (u8 *)dst, (u8 *)src);
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 			dst[1] ^= ivs[0];
206*4882a593Smuzhiyun 			dst[2] ^= ivs[1];
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 			nbytes -= bsize;
209*4882a593Smuzhiyun 			if (nbytes < bsize)
210*4882a593Smuzhiyun 				goto done;
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 			*dst ^= *(src - 1);
213*4882a593Smuzhiyun 			src -= 1;
214*4882a593Smuzhiyun 			dst -= 1;
215*4882a593Smuzhiyun 		} while (nbytes >= bsize * 3);
216*4882a593Smuzhiyun 	}
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun 	/* Handle leftovers */
219*4882a593Smuzhiyun 	for (;;) {
220*4882a593Smuzhiyun 		des3_ede_dec_blk(ctx, (u8 *)dst, (u8 *)src);
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 		nbytes -= bsize;
223*4882a593Smuzhiyun 		if (nbytes < bsize)
224*4882a593Smuzhiyun 			break;
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 		*dst ^= *(src - 1);
227*4882a593Smuzhiyun 		src -= 1;
228*4882a593Smuzhiyun 		dst -= 1;
229*4882a593Smuzhiyun 	}
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun done:
232*4882a593Smuzhiyun 	*dst ^= *(u64 *)walk->iv;
233*4882a593Smuzhiyun 	*(u64 *)walk->iv = last_iv;
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	return nbytes;
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun 
cbc_decrypt(struct skcipher_request * req)238*4882a593Smuzhiyun static int cbc_decrypt(struct skcipher_request *req)
239*4882a593Smuzhiyun {
240*4882a593Smuzhiyun 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
241*4882a593Smuzhiyun 	struct des3_ede_x86_ctx *ctx = crypto_skcipher_ctx(tfm);
242*4882a593Smuzhiyun 	struct skcipher_walk walk;
243*4882a593Smuzhiyun 	unsigned int nbytes;
244*4882a593Smuzhiyun 	int err;
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun 	err = skcipher_walk_virt(&walk, req, false);
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	while ((nbytes = walk.nbytes)) {
249*4882a593Smuzhiyun 		nbytes = __cbc_decrypt(ctx, &walk);
250*4882a593Smuzhiyun 		err = skcipher_walk_done(&walk, nbytes);
251*4882a593Smuzhiyun 	}
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	return err;
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun 
ctr_crypt_final(struct des3_ede_x86_ctx * ctx,struct skcipher_walk * walk)256*4882a593Smuzhiyun static void ctr_crypt_final(struct des3_ede_x86_ctx *ctx,
257*4882a593Smuzhiyun 			    struct skcipher_walk *walk)
258*4882a593Smuzhiyun {
259*4882a593Smuzhiyun 	u8 *ctrblk = walk->iv;
260*4882a593Smuzhiyun 	u8 keystream[DES3_EDE_BLOCK_SIZE];
261*4882a593Smuzhiyun 	u8 *src = walk->src.virt.addr;
262*4882a593Smuzhiyun 	u8 *dst = walk->dst.virt.addr;
263*4882a593Smuzhiyun 	unsigned int nbytes = walk->nbytes;
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 	des3_ede_enc_blk(ctx, keystream, ctrblk);
266*4882a593Smuzhiyun 	crypto_xor_cpy(dst, keystream, src, nbytes);
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	crypto_inc(ctrblk, DES3_EDE_BLOCK_SIZE);
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun 
__ctr_crypt(struct des3_ede_x86_ctx * ctx,struct skcipher_walk * walk)271*4882a593Smuzhiyun static unsigned int __ctr_crypt(struct des3_ede_x86_ctx *ctx,
272*4882a593Smuzhiyun 				struct skcipher_walk *walk)
273*4882a593Smuzhiyun {
274*4882a593Smuzhiyun 	unsigned int bsize = DES3_EDE_BLOCK_SIZE;
275*4882a593Smuzhiyun 	unsigned int nbytes = walk->nbytes;
276*4882a593Smuzhiyun 	__be64 *src = (__be64 *)walk->src.virt.addr;
277*4882a593Smuzhiyun 	__be64 *dst = (__be64 *)walk->dst.virt.addr;
278*4882a593Smuzhiyun 	u64 ctrblk = be64_to_cpu(*(__be64 *)walk->iv);
279*4882a593Smuzhiyun 	__be64 ctrblocks[3];
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun 	/* Process four block batch */
282*4882a593Smuzhiyun 	if (nbytes >= bsize * 3) {
283*4882a593Smuzhiyun 		do {
284*4882a593Smuzhiyun 			/* create ctrblks for parallel encrypt */
285*4882a593Smuzhiyun 			ctrblocks[0] = cpu_to_be64(ctrblk++);
286*4882a593Smuzhiyun 			ctrblocks[1] = cpu_to_be64(ctrblk++);
287*4882a593Smuzhiyun 			ctrblocks[2] = cpu_to_be64(ctrblk++);
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun 			des3_ede_enc_blk_3way(ctx, (u8 *)ctrblocks,
290*4882a593Smuzhiyun 					      (u8 *)ctrblocks);
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun 			dst[0] = src[0] ^ ctrblocks[0];
293*4882a593Smuzhiyun 			dst[1] = src[1] ^ ctrblocks[1];
294*4882a593Smuzhiyun 			dst[2] = src[2] ^ ctrblocks[2];
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun 			src += 3;
297*4882a593Smuzhiyun 			dst += 3;
298*4882a593Smuzhiyun 		} while ((nbytes -= bsize * 3) >= bsize * 3);
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 		if (nbytes < bsize)
301*4882a593Smuzhiyun 			goto done;
302*4882a593Smuzhiyun 	}
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun 	/* Handle leftovers */
305*4882a593Smuzhiyun 	do {
306*4882a593Smuzhiyun 		ctrblocks[0] = cpu_to_be64(ctrblk++);
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun 		des3_ede_enc_blk(ctx, (u8 *)ctrblocks, (u8 *)ctrblocks);
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 		dst[0] = src[0] ^ ctrblocks[0];
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 		src += 1;
313*4882a593Smuzhiyun 		dst += 1;
314*4882a593Smuzhiyun 	} while ((nbytes -= bsize) >= bsize);
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun done:
317*4882a593Smuzhiyun 	*(__be64 *)walk->iv = cpu_to_be64(ctrblk);
318*4882a593Smuzhiyun 	return nbytes;
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun 
ctr_crypt(struct skcipher_request * req)321*4882a593Smuzhiyun static int ctr_crypt(struct skcipher_request *req)
322*4882a593Smuzhiyun {
323*4882a593Smuzhiyun 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
324*4882a593Smuzhiyun 	struct des3_ede_x86_ctx *ctx = crypto_skcipher_ctx(tfm);
325*4882a593Smuzhiyun 	struct skcipher_walk walk;
326*4882a593Smuzhiyun 	unsigned int nbytes;
327*4882a593Smuzhiyun 	int err;
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 	err = skcipher_walk_virt(&walk, req, false);
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun 	while ((nbytes = walk.nbytes) >= DES3_EDE_BLOCK_SIZE) {
332*4882a593Smuzhiyun 		nbytes = __ctr_crypt(ctx, &walk);
333*4882a593Smuzhiyun 		err = skcipher_walk_done(&walk, nbytes);
334*4882a593Smuzhiyun 	}
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 	if (nbytes) {
337*4882a593Smuzhiyun 		ctr_crypt_final(ctx, &walk);
338*4882a593Smuzhiyun 		err = skcipher_walk_done(&walk, 0);
339*4882a593Smuzhiyun 	}
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun 	return err;
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun 
des3_ede_x86_setkey(struct crypto_tfm * tfm,const u8 * key,unsigned int keylen)344*4882a593Smuzhiyun static int des3_ede_x86_setkey(struct crypto_tfm *tfm, const u8 *key,
345*4882a593Smuzhiyun 			       unsigned int keylen)
346*4882a593Smuzhiyun {
347*4882a593Smuzhiyun 	struct des3_ede_x86_ctx *ctx = crypto_tfm_ctx(tfm);
348*4882a593Smuzhiyun 	u32 i, j, tmp;
349*4882a593Smuzhiyun 	int err;
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun 	err = des3_ede_expand_key(&ctx->enc, key, keylen);
352*4882a593Smuzhiyun 	if (err == -ENOKEY) {
353*4882a593Smuzhiyun 		if (crypto_tfm_get_flags(tfm) & CRYPTO_TFM_REQ_FORBID_WEAK_KEYS)
354*4882a593Smuzhiyun 			err = -EINVAL;
355*4882a593Smuzhiyun 		else
356*4882a593Smuzhiyun 			err = 0;
357*4882a593Smuzhiyun 	}
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	if (err) {
360*4882a593Smuzhiyun 		memset(ctx, 0, sizeof(*ctx));
361*4882a593Smuzhiyun 		return err;
362*4882a593Smuzhiyun 	}
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	/* Fix encryption context for this implementation and form decryption
365*4882a593Smuzhiyun 	 * context. */
366*4882a593Smuzhiyun 	j = DES3_EDE_EXPKEY_WORDS - 2;
367*4882a593Smuzhiyun 	for (i = 0; i < DES3_EDE_EXPKEY_WORDS; i += 2, j -= 2) {
368*4882a593Smuzhiyun 		tmp = ror32(ctx->enc.expkey[i + 1], 4);
369*4882a593Smuzhiyun 		ctx->enc.expkey[i + 1] = tmp;
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 		ctx->dec.expkey[j + 0] = ctx->enc.expkey[i + 0];
372*4882a593Smuzhiyun 		ctx->dec.expkey[j + 1] = tmp;
373*4882a593Smuzhiyun 	}
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 	return 0;
376*4882a593Smuzhiyun }
377*4882a593Smuzhiyun 
des3_ede_x86_setkey_skcipher(struct crypto_skcipher * tfm,const u8 * key,unsigned int keylen)378*4882a593Smuzhiyun static int des3_ede_x86_setkey_skcipher(struct crypto_skcipher *tfm,
379*4882a593Smuzhiyun 					const u8 *key,
380*4882a593Smuzhiyun 					unsigned int keylen)
381*4882a593Smuzhiyun {
382*4882a593Smuzhiyun 	return des3_ede_x86_setkey(&tfm->base, key, keylen);
383*4882a593Smuzhiyun }
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun static struct crypto_alg des3_ede_cipher = {
386*4882a593Smuzhiyun 	.cra_name		= "des3_ede",
387*4882a593Smuzhiyun 	.cra_driver_name	= "des3_ede-asm",
388*4882a593Smuzhiyun 	.cra_priority		= 200,
389*4882a593Smuzhiyun 	.cra_flags		= CRYPTO_ALG_TYPE_CIPHER,
390*4882a593Smuzhiyun 	.cra_blocksize		= DES3_EDE_BLOCK_SIZE,
391*4882a593Smuzhiyun 	.cra_ctxsize		= sizeof(struct des3_ede_x86_ctx),
392*4882a593Smuzhiyun 	.cra_alignmask		= 0,
393*4882a593Smuzhiyun 	.cra_module		= THIS_MODULE,
394*4882a593Smuzhiyun 	.cra_u = {
395*4882a593Smuzhiyun 		.cipher = {
396*4882a593Smuzhiyun 			.cia_min_keysize	= DES3_EDE_KEY_SIZE,
397*4882a593Smuzhiyun 			.cia_max_keysize	= DES3_EDE_KEY_SIZE,
398*4882a593Smuzhiyun 			.cia_setkey		= des3_ede_x86_setkey,
399*4882a593Smuzhiyun 			.cia_encrypt		= des3_ede_x86_encrypt,
400*4882a593Smuzhiyun 			.cia_decrypt		= des3_ede_x86_decrypt,
401*4882a593Smuzhiyun 		}
402*4882a593Smuzhiyun 	}
403*4882a593Smuzhiyun };
404*4882a593Smuzhiyun 
405*4882a593Smuzhiyun static struct skcipher_alg des3_ede_skciphers[] = {
406*4882a593Smuzhiyun 	{
407*4882a593Smuzhiyun 		.base.cra_name		= "ecb(des3_ede)",
408*4882a593Smuzhiyun 		.base.cra_driver_name	= "ecb-des3_ede-asm",
409*4882a593Smuzhiyun 		.base.cra_priority	= 300,
410*4882a593Smuzhiyun 		.base.cra_blocksize	= DES3_EDE_BLOCK_SIZE,
411*4882a593Smuzhiyun 		.base.cra_ctxsize	= sizeof(struct des3_ede_x86_ctx),
412*4882a593Smuzhiyun 		.base.cra_module	= THIS_MODULE,
413*4882a593Smuzhiyun 		.min_keysize		= DES3_EDE_KEY_SIZE,
414*4882a593Smuzhiyun 		.max_keysize		= DES3_EDE_KEY_SIZE,
415*4882a593Smuzhiyun 		.setkey			= des3_ede_x86_setkey_skcipher,
416*4882a593Smuzhiyun 		.encrypt		= ecb_encrypt,
417*4882a593Smuzhiyun 		.decrypt		= ecb_decrypt,
418*4882a593Smuzhiyun 	}, {
419*4882a593Smuzhiyun 		.base.cra_name		= "cbc(des3_ede)",
420*4882a593Smuzhiyun 		.base.cra_driver_name	= "cbc-des3_ede-asm",
421*4882a593Smuzhiyun 		.base.cra_priority	= 300,
422*4882a593Smuzhiyun 		.base.cra_blocksize	= DES3_EDE_BLOCK_SIZE,
423*4882a593Smuzhiyun 		.base.cra_ctxsize	= sizeof(struct des3_ede_x86_ctx),
424*4882a593Smuzhiyun 		.base.cra_module	= THIS_MODULE,
425*4882a593Smuzhiyun 		.min_keysize		= DES3_EDE_KEY_SIZE,
426*4882a593Smuzhiyun 		.max_keysize		= DES3_EDE_KEY_SIZE,
427*4882a593Smuzhiyun 		.ivsize			= DES3_EDE_BLOCK_SIZE,
428*4882a593Smuzhiyun 		.setkey			= des3_ede_x86_setkey_skcipher,
429*4882a593Smuzhiyun 		.encrypt		= cbc_encrypt,
430*4882a593Smuzhiyun 		.decrypt		= cbc_decrypt,
431*4882a593Smuzhiyun 	}, {
432*4882a593Smuzhiyun 		.base.cra_name		= "ctr(des3_ede)",
433*4882a593Smuzhiyun 		.base.cra_driver_name	= "ctr-des3_ede-asm",
434*4882a593Smuzhiyun 		.base.cra_priority	= 300,
435*4882a593Smuzhiyun 		.base.cra_blocksize	= 1,
436*4882a593Smuzhiyun 		.base.cra_ctxsize	= sizeof(struct des3_ede_x86_ctx),
437*4882a593Smuzhiyun 		.base.cra_module	= THIS_MODULE,
438*4882a593Smuzhiyun 		.min_keysize		= DES3_EDE_KEY_SIZE,
439*4882a593Smuzhiyun 		.max_keysize		= DES3_EDE_KEY_SIZE,
440*4882a593Smuzhiyun 		.ivsize			= DES3_EDE_BLOCK_SIZE,
441*4882a593Smuzhiyun 		.chunksize		= DES3_EDE_BLOCK_SIZE,
442*4882a593Smuzhiyun 		.setkey			= des3_ede_x86_setkey_skcipher,
443*4882a593Smuzhiyun 		.encrypt		= ctr_crypt,
444*4882a593Smuzhiyun 		.decrypt		= ctr_crypt,
445*4882a593Smuzhiyun 	}
446*4882a593Smuzhiyun };
447*4882a593Smuzhiyun 
is_blacklisted_cpu(void)448*4882a593Smuzhiyun static bool is_blacklisted_cpu(void)
449*4882a593Smuzhiyun {
450*4882a593Smuzhiyun 	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
451*4882a593Smuzhiyun 		return false;
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun 	if (boot_cpu_data.x86 == 0x0f) {
454*4882a593Smuzhiyun 		/*
455*4882a593Smuzhiyun 		 * On Pentium 4, des3_ede-x86_64 is slower than generic C
456*4882a593Smuzhiyun 		 * implementation because use of 64bit rotates (which are really
457*4882a593Smuzhiyun 		 * slow on P4). Therefore blacklist P4s.
458*4882a593Smuzhiyun 		 */
459*4882a593Smuzhiyun 		return true;
460*4882a593Smuzhiyun 	}
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun 	return false;
463*4882a593Smuzhiyun }
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun static int force;
466*4882a593Smuzhiyun module_param(force, int, 0);
467*4882a593Smuzhiyun MODULE_PARM_DESC(force, "Force module load, ignore CPU blacklist");
468*4882a593Smuzhiyun 
des3_ede_x86_init(void)469*4882a593Smuzhiyun static int __init des3_ede_x86_init(void)
470*4882a593Smuzhiyun {
471*4882a593Smuzhiyun 	int err;
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun 	if (!force && is_blacklisted_cpu()) {
474*4882a593Smuzhiyun 		pr_info("des3_ede-x86_64: performance on this CPU would be suboptimal: disabling des3_ede-x86_64.\n");
475*4882a593Smuzhiyun 		return -ENODEV;
476*4882a593Smuzhiyun 	}
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun 	err = crypto_register_alg(&des3_ede_cipher);
479*4882a593Smuzhiyun 	if (err)
480*4882a593Smuzhiyun 		return err;
481*4882a593Smuzhiyun 
482*4882a593Smuzhiyun 	err = crypto_register_skciphers(des3_ede_skciphers,
483*4882a593Smuzhiyun 					ARRAY_SIZE(des3_ede_skciphers));
484*4882a593Smuzhiyun 	if (err)
485*4882a593Smuzhiyun 		crypto_unregister_alg(&des3_ede_cipher);
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun 	return err;
488*4882a593Smuzhiyun }
489*4882a593Smuzhiyun 
des3_ede_x86_fini(void)490*4882a593Smuzhiyun static void __exit des3_ede_x86_fini(void)
491*4882a593Smuzhiyun {
492*4882a593Smuzhiyun 	crypto_unregister_alg(&des3_ede_cipher);
493*4882a593Smuzhiyun 	crypto_unregister_skciphers(des3_ede_skciphers,
494*4882a593Smuzhiyun 				    ARRAY_SIZE(des3_ede_skciphers));
495*4882a593Smuzhiyun }
496*4882a593Smuzhiyun 
497*4882a593Smuzhiyun module_init(des3_ede_x86_init);
498*4882a593Smuzhiyun module_exit(des3_ede_x86_fini);
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun MODULE_LICENSE("GPL");
501*4882a593Smuzhiyun MODULE_DESCRIPTION("Triple DES EDE Cipher Algorithm, asm optimized");
502*4882a593Smuzhiyun MODULE_ALIAS_CRYPTO("des3_ede");
503*4882a593Smuzhiyun MODULE_ALIAS_CRYPTO("des3_ede-asm");
504*4882a593Smuzhiyun MODULE_AUTHOR("Jussi Kivilinna <jussi.kivilinna@iki.fi>");
505