xref: /openbmc/linux/arch/arm64/crypto/aes-neonbs-glue.c (revision 1abee99eafab67fb1c98f9ecfc43cd5735384a86)
1*1abee99eSArd Biesheuvel /*
2*1abee99eSArd Biesheuvel  * Bit sliced AES using NEON instructions
3*1abee99eSArd Biesheuvel  *
4*1abee99eSArd Biesheuvel  * Copyright (C) 2016 Linaro Ltd <ard.biesheuvel@linaro.org>
5*1abee99eSArd Biesheuvel  *
6*1abee99eSArd Biesheuvel  * This program is free software; you can redistribute it and/or modify
7*1abee99eSArd Biesheuvel  * it under the terms of the GNU General Public License version 2 as
8*1abee99eSArd Biesheuvel  * published by the Free Software Foundation.
9*1abee99eSArd Biesheuvel  */
10*1abee99eSArd Biesheuvel 
11*1abee99eSArd Biesheuvel #include <asm/neon.h>
12*1abee99eSArd Biesheuvel #include <crypto/aes.h>
13*1abee99eSArd Biesheuvel #include <crypto/cbc.h>
14*1abee99eSArd Biesheuvel #include <crypto/internal/simd.h>
15*1abee99eSArd Biesheuvel #include <crypto/internal/skcipher.h>
16*1abee99eSArd Biesheuvel #include <crypto/xts.h>
17*1abee99eSArd Biesheuvel #include <linux/module.h>
18*1abee99eSArd Biesheuvel 
19*1abee99eSArd Biesheuvel MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
20*1abee99eSArd Biesheuvel MODULE_LICENSE("GPL v2");
21*1abee99eSArd Biesheuvel 
22*1abee99eSArd Biesheuvel MODULE_ALIAS_CRYPTO("ecb(aes)");
23*1abee99eSArd Biesheuvel MODULE_ALIAS_CRYPTO("cbc(aes)");
24*1abee99eSArd Biesheuvel MODULE_ALIAS_CRYPTO("ctr(aes)");
25*1abee99eSArd Biesheuvel MODULE_ALIAS_CRYPTO("xts(aes)");
26*1abee99eSArd Biesheuvel 
27*1abee99eSArd Biesheuvel asmlinkage void aesbs_convert_key(u8 out[], u32 const rk[], int rounds);
28*1abee99eSArd Biesheuvel 
29*1abee99eSArd Biesheuvel asmlinkage void aesbs_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[],
30*1abee99eSArd Biesheuvel 				  int rounds, int blocks);
31*1abee99eSArd Biesheuvel asmlinkage void aesbs_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[],
32*1abee99eSArd Biesheuvel 				  int rounds, int blocks);
33*1abee99eSArd Biesheuvel 
34*1abee99eSArd Biesheuvel asmlinkage void aesbs_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[],
35*1abee99eSArd Biesheuvel 				  int rounds, int blocks, u8 iv[]);
36*1abee99eSArd Biesheuvel 
37*1abee99eSArd Biesheuvel asmlinkage void aesbs_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
38*1abee99eSArd Biesheuvel 				  int rounds, int blocks, u8 iv[], bool final);
39*1abee99eSArd Biesheuvel 
40*1abee99eSArd Biesheuvel asmlinkage void aesbs_xts_encrypt(u8 out[], u8 const in[], u8 const rk[],
41*1abee99eSArd Biesheuvel 				  int rounds, int blocks, u8 iv[]);
42*1abee99eSArd Biesheuvel asmlinkage void aesbs_xts_decrypt(u8 out[], u8 const in[], u8 const rk[],
43*1abee99eSArd Biesheuvel 				  int rounds, int blocks, u8 iv[]);
44*1abee99eSArd Biesheuvel 
45*1abee99eSArd Biesheuvel asmlinkage void __aes_arm64_encrypt(u32 *rk, u8 *out, const u8 *in, int rounds);
46*1abee99eSArd Biesheuvel 
47*1abee99eSArd Biesheuvel struct aesbs_ctx {
48*1abee99eSArd Biesheuvel 	u8	rk[13 * (8 * AES_BLOCK_SIZE) + 32];
49*1abee99eSArd Biesheuvel 	int	rounds;
50*1abee99eSArd Biesheuvel } __aligned(AES_BLOCK_SIZE);
51*1abee99eSArd Biesheuvel 
52*1abee99eSArd Biesheuvel struct aesbs_cbc_ctx {
53*1abee99eSArd Biesheuvel 	struct aesbs_ctx	key;
54*1abee99eSArd Biesheuvel 	u32			enc[AES_MAX_KEYLENGTH_U32];
55*1abee99eSArd Biesheuvel };
56*1abee99eSArd Biesheuvel 
57*1abee99eSArd Biesheuvel struct aesbs_xts_ctx {
58*1abee99eSArd Biesheuvel 	struct aesbs_ctx	key;
59*1abee99eSArd Biesheuvel 	u32			twkey[AES_MAX_KEYLENGTH_U32];
60*1abee99eSArd Biesheuvel };
61*1abee99eSArd Biesheuvel 
62*1abee99eSArd Biesheuvel static int aesbs_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
63*1abee99eSArd Biesheuvel 			unsigned int key_len)
64*1abee99eSArd Biesheuvel {
65*1abee99eSArd Biesheuvel 	struct aesbs_ctx *ctx = crypto_skcipher_ctx(tfm);
66*1abee99eSArd Biesheuvel 	struct crypto_aes_ctx rk;
67*1abee99eSArd Biesheuvel 	int err;
68*1abee99eSArd Biesheuvel 
69*1abee99eSArd Biesheuvel 	err = crypto_aes_expand_key(&rk, in_key, key_len);
70*1abee99eSArd Biesheuvel 	if (err)
71*1abee99eSArd Biesheuvel 		return err;
72*1abee99eSArd Biesheuvel 
73*1abee99eSArd Biesheuvel 	ctx->rounds = 6 + key_len / 4;
74*1abee99eSArd Biesheuvel 
75*1abee99eSArd Biesheuvel 	kernel_neon_begin();
76*1abee99eSArd Biesheuvel 	aesbs_convert_key(ctx->rk, rk.key_enc, ctx->rounds);
77*1abee99eSArd Biesheuvel 	kernel_neon_end();
78*1abee99eSArd Biesheuvel 
79*1abee99eSArd Biesheuvel 	return 0;
80*1abee99eSArd Biesheuvel }
81*1abee99eSArd Biesheuvel 
82*1abee99eSArd Biesheuvel static int __ecb_crypt(struct skcipher_request *req,
83*1abee99eSArd Biesheuvel 		       void (*fn)(u8 out[], u8 const in[], u8 const rk[],
84*1abee99eSArd Biesheuvel 				  int rounds, int blocks))
85*1abee99eSArd Biesheuvel {
86*1abee99eSArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
87*1abee99eSArd Biesheuvel 	struct aesbs_ctx *ctx = crypto_skcipher_ctx(tfm);
88*1abee99eSArd Biesheuvel 	struct skcipher_walk walk;
89*1abee99eSArd Biesheuvel 	int err;
90*1abee99eSArd Biesheuvel 
91*1abee99eSArd Biesheuvel 	err = skcipher_walk_virt(&walk, req, true);
92*1abee99eSArd Biesheuvel 
93*1abee99eSArd Biesheuvel 	kernel_neon_begin();
94*1abee99eSArd Biesheuvel 	while (walk.nbytes >= AES_BLOCK_SIZE) {
95*1abee99eSArd Biesheuvel 		unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE;
96*1abee99eSArd Biesheuvel 
97*1abee99eSArd Biesheuvel 		if (walk.nbytes < walk.total)
98*1abee99eSArd Biesheuvel 			blocks = round_down(blocks,
99*1abee99eSArd Biesheuvel 					    walk.stride / AES_BLOCK_SIZE);
100*1abee99eSArd Biesheuvel 
101*1abee99eSArd Biesheuvel 		fn(walk.dst.virt.addr, walk.src.virt.addr, ctx->rk,
102*1abee99eSArd Biesheuvel 		   ctx->rounds, blocks);
103*1abee99eSArd Biesheuvel 		err = skcipher_walk_done(&walk,
104*1abee99eSArd Biesheuvel 					 walk.nbytes - blocks * AES_BLOCK_SIZE);
105*1abee99eSArd Biesheuvel 	}
106*1abee99eSArd Biesheuvel 	kernel_neon_end();
107*1abee99eSArd Biesheuvel 
108*1abee99eSArd Biesheuvel 	return err;
109*1abee99eSArd Biesheuvel }
110*1abee99eSArd Biesheuvel 
111*1abee99eSArd Biesheuvel static int ecb_encrypt(struct skcipher_request *req)
112*1abee99eSArd Biesheuvel {
113*1abee99eSArd Biesheuvel 	return __ecb_crypt(req, aesbs_ecb_encrypt);
114*1abee99eSArd Biesheuvel }
115*1abee99eSArd Biesheuvel 
116*1abee99eSArd Biesheuvel static int ecb_decrypt(struct skcipher_request *req)
117*1abee99eSArd Biesheuvel {
118*1abee99eSArd Biesheuvel 	return __ecb_crypt(req, aesbs_ecb_decrypt);
119*1abee99eSArd Biesheuvel }
120*1abee99eSArd Biesheuvel 
121*1abee99eSArd Biesheuvel static int aesbs_cbc_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
122*1abee99eSArd Biesheuvel 			    unsigned int key_len)
123*1abee99eSArd Biesheuvel {
124*1abee99eSArd Biesheuvel 	struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
125*1abee99eSArd Biesheuvel 	struct crypto_aes_ctx rk;
126*1abee99eSArd Biesheuvel 	int err;
127*1abee99eSArd Biesheuvel 
128*1abee99eSArd Biesheuvel 	err = crypto_aes_expand_key(&rk, in_key, key_len);
129*1abee99eSArd Biesheuvel 	if (err)
130*1abee99eSArd Biesheuvel 		return err;
131*1abee99eSArd Biesheuvel 
132*1abee99eSArd Biesheuvel 	ctx->key.rounds = 6 + key_len / 4;
133*1abee99eSArd Biesheuvel 
134*1abee99eSArd Biesheuvel 	memcpy(ctx->enc, rk.key_enc, sizeof(ctx->enc));
135*1abee99eSArd Biesheuvel 
136*1abee99eSArd Biesheuvel 	kernel_neon_begin();
137*1abee99eSArd Biesheuvel 	aesbs_convert_key(ctx->key.rk, rk.key_enc, ctx->key.rounds);
138*1abee99eSArd Biesheuvel 	kernel_neon_end();
139*1abee99eSArd Biesheuvel 
140*1abee99eSArd Biesheuvel 	return 0;
141*1abee99eSArd Biesheuvel }
142*1abee99eSArd Biesheuvel 
143*1abee99eSArd Biesheuvel static void cbc_encrypt_one(struct crypto_skcipher *tfm, const u8 *src, u8 *dst)
144*1abee99eSArd Biesheuvel {
145*1abee99eSArd Biesheuvel 	struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
146*1abee99eSArd Biesheuvel 
147*1abee99eSArd Biesheuvel 	__aes_arm64_encrypt(ctx->enc, dst, src, ctx->key.rounds);
148*1abee99eSArd Biesheuvel }
149*1abee99eSArd Biesheuvel 
150*1abee99eSArd Biesheuvel static int cbc_encrypt(struct skcipher_request *req)
151*1abee99eSArd Biesheuvel {
152*1abee99eSArd Biesheuvel 	return crypto_cbc_encrypt_walk(req, cbc_encrypt_one);
153*1abee99eSArd Biesheuvel }
154*1abee99eSArd Biesheuvel 
155*1abee99eSArd Biesheuvel static int cbc_decrypt(struct skcipher_request *req)
156*1abee99eSArd Biesheuvel {
157*1abee99eSArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
158*1abee99eSArd Biesheuvel 	struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
159*1abee99eSArd Biesheuvel 	struct skcipher_walk walk;
160*1abee99eSArd Biesheuvel 	int err;
161*1abee99eSArd Biesheuvel 
162*1abee99eSArd Biesheuvel 	err = skcipher_walk_virt(&walk, req, true);
163*1abee99eSArd Biesheuvel 
164*1abee99eSArd Biesheuvel 	kernel_neon_begin();
165*1abee99eSArd Biesheuvel 	while (walk.nbytes >= AES_BLOCK_SIZE) {
166*1abee99eSArd Biesheuvel 		unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE;
167*1abee99eSArd Biesheuvel 
168*1abee99eSArd Biesheuvel 		if (walk.nbytes < walk.total)
169*1abee99eSArd Biesheuvel 			blocks = round_down(blocks,
170*1abee99eSArd Biesheuvel 					    walk.stride / AES_BLOCK_SIZE);
171*1abee99eSArd Biesheuvel 
172*1abee99eSArd Biesheuvel 		aesbs_cbc_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
173*1abee99eSArd Biesheuvel 				  ctx->key.rk, ctx->key.rounds, blocks,
174*1abee99eSArd Biesheuvel 				  walk.iv);
175*1abee99eSArd Biesheuvel 		err = skcipher_walk_done(&walk,
176*1abee99eSArd Biesheuvel 					 walk.nbytes - blocks * AES_BLOCK_SIZE);
177*1abee99eSArd Biesheuvel 	}
178*1abee99eSArd Biesheuvel 	kernel_neon_end();
179*1abee99eSArd Biesheuvel 
180*1abee99eSArd Biesheuvel 	return err;
181*1abee99eSArd Biesheuvel }
182*1abee99eSArd Biesheuvel 
183*1abee99eSArd Biesheuvel static int ctr_encrypt(struct skcipher_request *req)
184*1abee99eSArd Biesheuvel {
185*1abee99eSArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
186*1abee99eSArd Biesheuvel 	struct aesbs_ctx *ctx = crypto_skcipher_ctx(tfm);
187*1abee99eSArd Biesheuvel 	struct skcipher_walk walk;
188*1abee99eSArd Biesheuvel 	int err;
189*1abee99eSArd Biesheuvel 
190*1abee99eSArd Biesheuvel 	err = skcipher_walk_virt(&walk, req, true);
191*1abee99eSArd Biesheuvel 
192*1abee99eSArd Biesheuvel 	kernel_neon_begin();
193*1abee99eSArd Biesheuvel 	while (walk.nbytes > 0) {
194*1abee99eSArd Biesheuvel 		unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE;
195*1abee99eSArd Biesheuvel 		bool final = (walk.total % AES_BLOCK_SIZE) != 0;
196*1abee99eSArd Biesheuvel 
197*1abee99eSArd Biesheuvel 		if (walk.nbytes < walk.total) {
198*1abee99eSArd Biesheuvel 			blocks = round_down(blocks,
199*1abee99eSArd Biesheuvel 					    walk.stride / AES_BLOCK_SIZE);
200*1abee99eSArd Biesheuvel 			final = false;
201*1abee99eSArd Biesheuvel 		}
202*1abee99eSArd Biesheuvel 
203*1abee99eSArd Biesheuvel 		aesbs_ctr_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
204*1abee99eSArd Biesheuvel 				  ctx->rk, ctx->rounds, blocks, walk.iv, final);
205*1abee99eSArd Biesheuvel 
206*1abee99eSArd Biesheuvel 		if (final) {
207*1abee99eSArd Biesheuvel 			u8 *dst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
208*1abee99eSArd Biesheuvel 			u8 *src = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
209*1abee99eSArd Biesheuvel 
210*1abee99eSArd Biesheuvel 			if (dst != src)
211*1abee99eSArd Biesheuvel 				memcpy(dst, src, walk.total % AES_BLOCK_SIZE);
212*1abee99eSArd Biesheuvel 			crypto_xor(dst, walk.iv, walk.total % AES_BLOCK_SIZE);
213*1abee99eSArd Biesheuvel 
214*1abee99eSArd Biesheuvel 			err = skcipher_walk_done(&walk, 0);
215*1abee99eSArd Biesheuvel 			break;
216*1abee99eSArd Biesheuvel 		}
217*1abee99eSArd Biesheuvel 		err = skcipher_walk_done(&walk,
218*1abee99eSArd Biesheuvel 					 walk.nbytes - blocks * AES_BLOCK_SIZE);
219*1abee99eSArd Biesheuvel 	}
220*1abee99eSArd Biesheuvel 	kernel_neon_end();
221*1abee99eSArd Biesheuvel 
222*1abee99eSArd Biesheuvel 	return err;
223*1abee99eSArd Biesheuvel }
224*1abee99eSArd Biesheuvel 
225*1abee99eSArd Biesheuvel static int aesbs_xts_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
226*1abee99eSArd Biesheuvel 			    unsigned int key_len)
227*1abee99eSArd Biesheuvel {
228*1abee99eSArd Biesheuvel 	struct aesbs_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
229*1abee99eSArd Biesheuvel 	struct crypto_aes_ctx rk;
230*1abee99eSArd Biesheuvel 	int err;
231*1abee99eSArd Biesheuvel 
232*1abee99eSArd Biesheuvel 	err = xts_verify_key(tfm, in_key, key_len);
233*1abee99eSArd Biesheuvel 	if (err)
234*1abee99eSArd Biesheuvel 		return err;
235*1abee99eSArd Biesheuvel 
236*1abee99eSArd Biesheuvel 	key_len /= 2;
237*1abee99eSArd Biesheuvel 	err = crypto_aes_expand_key(&rk, in_key + key_len, key_len);
238*1abee99eSArd Biesheuvel 	if (err)
239*1abee99eSArd Biesheuvel 		return err;
240*1abee99eSArd Biesheuvel 
241*1abee99eSArd Biesheuvel 	memcpy(ctx->twkey, rk.key_enc, sizeof(ctx->twkey));
242*1abee99eSArd Biesheuvel 
243*1abee99eSArd Biesheuvel 	return aesbs_setkey(tfm, in_key, key_len);
244*1abee99eSArd Biesheuvel }
245*1abee99eSArd Biesheuvel 
246*1abee99eSArd Biesheuvel static int __xts_crypt(struct skcipher_request *req,
247*1abee99eSArd Biesheuvel 		       void (*fn)(u8 out[], u8 const in[], u8 const rk[],
248*1abee99eSArd Biesheuvel 				  int rounds, int blocks, u8 iv[]))
249*1abee99eSArd Biesheuvel {
250*1abee99eSArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
251*1abee99eSArd Biesheuvel 	struct aesbs_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
252*1abee99eSArd Biesheuvel 	struct skcipher_walk walk;
253*1abee99eSArd Biesheuvel 	int err;
254*1abee99eSArd Biesheuvel 
255*1abee99eSArd Biesheuvel 	err = skcipher_walk_virt(&walk, req, true);
256*1abee99eSArd Biesheuvel 
257*1abee99eSArd Biesheuvel 	__aes_arm64_encrypt(ctx->twkey, walk.iv, walk.iv, ctx->key.rounds);
258*1abee99eSArd Biesheuvel 
259*1abee99eSArd Biesheuvel 	kernel_neon_begin();
260*1abee99eSArd Biesheuvel 	while (walk.nbytes >= AES_BLOCK_SIZE) {
261*1abee99eSArd Biesheuvel 		unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE;
262*1abee99eSArd Biesheuvel 
263*1abee99eSArd Biesheuvel 		if (walk.nbytes < walk.total)
264*1abee99eSArd Biesheuvel 			blocks = round_down(blocks,
265*1abee99eSArd Biesheuvel 					    walk.stride / AES_BLOCK_SIZE);
266*1abee99eSArd Biesheuvel 
267*1abee99eSArd Biesheuvel 		fn(walk.dst.virt.addr, walk.src.virt.addr, ctx->key.rk,
268*1abee99eSArd Biesheuvel 		   ctx->key.rounds, blocks, walk.iv);
269*1abee99eSArd Biesheuvel 		err = skcipher_walk_done(&walk,
270*1abee99eSArd Biesheuvel 					 walk.nbytes - blocks * AES_BLOCK_SIZE);
271*1abee99eSArd Biesheuvel 	}
272*1abee99eSArd Biesheuvel 	kernel_neon_end();
273*1abee99eSArd Biesheuvel 
274*1abee99eSArd Biesheuvel 	return err;
275*1abee99eSArd Biesheuvel }
276*1abee99eSArd Biesheuvel 
277*1abee99eSArd Biesheuvel static int xts_encrypt(struct skcipher_request *req)
278*1abee99eSArd Biesheuvel {
279*1abee99eSArd Biesheuvel 	return __xts_crypt(req, aesbs_xts_encrypt);
280*1abee99eSArd Biesheuvel }
281*1abee99eSArd Biesheuvel 
282*1abee99eSArd Biesheuvel static int xts_decrypt(struct skcipher_request *req)
283*1abee99eSArd Biesheuvel {
284*1abee99eSArd Biesheuvel 	return __xts_crypt(req, aesbs_xts_decrypt);
285*1abee99eSArd Biesheuvel }
286*1abee99eSArd Biesheuvel 
287*1abee99eSArd Biesheuvel static struct skcipher_alg aes_algs[] = { {
288*1abee99eSArd Biesheuvel 	.base.cra_name		= "__ecb(aes)",
289*1abee99eSArd Biesheuvel 	.base.cra_driver_name	= "__ecb-aes-neonbs",
290*1abee99eSArd Biesheuvel 	.base.cra_priority	= 250,
291*1abee99eSArd Biesheuvel 	.base.cra_blocksize	= AES_BLOCK_SIZE,
292*1abee99eSArd Biesheuvel 	.base.cra_ctxsize	= sizeof(struct aesbs_ctx),
293*1abee99eSArd Biesheuvel 	.base.cra_module	= THIS_MODULE,
294*1abee99eSArd Biesheuvel 	.base.cra_flags		= CRYPTO_ALG_INTERNAL,
295*1abee99eSArd Biesheuvel 
296*1abee99eSArd Biesheuvel 	.min_keysize		= AES_MIN_KEY_SIZE,
297*1abee99eSArd Biesheuvel 	.max_keysize		= AES_MAX_KEY_SIZE,
298*1abee99eSArd Biesheuvel 	.walksize		= 8 * AES_BLOCK_SIZE,
299*1abee99eSArd Biesheuvel 	.setkey			= aesbs_setkey,
300*1abee99eSArd Biesheuvel 	.encrypt		= ecb_encrypt,
301*1abee99eSArd Biesheuvel 	.decrypt		= ecb_decrypt,
302*1abee99eSArd Biesheuvel }, {
303*1abee99eSArd Biesheuvel 	.base.cra_name		= "__cbc(aes)",
304*1abee99eSArd Biesheuvel 	.base.cra_driver_name	= "__cbc-aes-neonbs",
305*1abee99eSArd Biesheuvel 	.base.cra_priority	= 250,
306*1abee99eSArd Biesheuvel 	.base.cra_blocksize	= AES_BLOCK_SIZE,
307*1abee99eSArd Biesheuvel 	.base.cra_ctxsize	= sizeof(struct aesbs_cbc_ctx),
308*1abee99eSArd Biesheuvel 	.base.cra_module	= THIS_MODULE,
309*1abee99eSArd Biesheuvel 	.base.cra_flags		= CRYPTO_ALG_INTERNAL,
310*1abee99eSArd Biesheuvel 
311*1abee99eSArd Biesheuvel 	.min_keysize		= AES_MIN_KEY_SIZE,
312*1abee99eSArd Biesheuvel 	.max_keysize		= AES_MAX_KEY_SIZE,
313*1abee99eSArd Biesheuvel 	.walksize		= 8 * AES_BLOCK_SIZE,
314*1abee99eSArd Biesheuvel 	.ivsize			= AES_BLOCK_SIZE,
315*1abee99eSArd Biesheuvel 	.setkey			= aesbs_cbc_setkey,
316*1abee99eSArd Biesheuvel 	.encrypt		= cbc_encrypt,
317*1abee99eSArd Biesheuvel 	.decrypt		= cbc_decrypt,
318*1abee99eSArd Biesheuvel }, {
319*1abee99eSArd Biesheuvel 	.base.cra_name		= "__ctr(aes)",
320*1abee99eSArd Biesheuvel 	.base.cra_driver_name	= "__ctr-aes-neonbs",
321*1abee99eSArd Biesheuvel 	.base.cra_priority	= 250,
322*1abee99eSArd Biesheuvel 	.base.cra_blocksize	= 1,
323*1abee99eSArd Biesheuvel 	.base.cra_ctxsize	= sizeof(struct aesbs_ctx),
324*1abee99eSArd Biesheuvel 	.base.cra_module	= THIS_MODULE,
325*1abee99eSArd Biesheuvel 	.base.cra_flags		= CRYPTO_ALG_INTERNAL,
326*1abee99eSArd Biesheuvel 
327*1abee99eSArd Biesheuvel 	.min_keysize		= AES_MIN_KEY_SIZE,
328*1abee99eSArd Biesheuvel 	.max_keysize		= AES_MAX_KEY_SIZE,
329*1abee99eSArd Biesheuvel 	.chunksize		= AES_BLOCK_SIZE,
330*1abee99eSArd Biesheuvel 	.walksize		= 8 * AES_BLOCK_SIZE,
331*1abee99eSArd Biesheuvel 	.ivsize			= AES_BLOCK_SIZE,
332*1abee99eSArd Biesheuvel 	.setkey			= aesbs_setkey,
333*1abee99eSArd Biesheuvel 	.encrypt		= ctr_encrypt,
334*1abee99eSArd Biesheuvel 	.decrypt		= ctr_encrypt,
335*1abee99eSArd Biesheuvel }, {
336*1abee99eSArd Biesheuvel 	.base.cra_name		= "ctr(aes)",
337*1abee99eSArd Biesheuvel 	.base.cra_driver_name	= "ctr-aes-neonbs",
338*1abee99eSArd Biesheuvel 	.base.cra_priority	= 250 - 1,
339*1abee99eSArd Biesheuvel 	.base.cra_blocksize	= 1,
340*1abee99eSArd Biesheuvel 	.base.cra_ctxsize	= sizeof(struct aesbs_ctx),
341*1abee99eSArd Biesheuvel 	.base.cra_module	= THIS_MODULE,
342*1abee99eSArd Biesheuvel 
343*1abee99eSArd Biesheuvel 	.min_keysize		= AES_MIN_KEY_SIZE,
344*1abee99eSArd Biesheuvel 	.max_keysize		= AES_MAX_KEY_SIZE,
345*1abee99eSArd Biesheuvel 	.chunksize		= AES_BLOCK_SIZE,
346*1abee99eSArd Biesheuvel 	.walksize		= 8 * AES_BLOCK_SIZE,
347*1abee99eSArd Biesheuvel 	.ivsize			= AES_BLOCK_SIZE,
348*1abee99eSArd Biesheuvel 	.setkey			= aesbs_setkey,
349*1abee99eSArd Biesheuvel 	.encrypt		= ctr_encrypt,
350*1abee99eSArd Biesheuvel 	.decrypt		= ctr_encrypt,
351*1abee99eSArd Biesheuvel }, {
352*1abee99eSArd Biesheuvel 	.base.cra_name		= "__xts(aes)",
353*1abee99eSArd Biesheuvel 	.base.cra_driver_name	= "__xts-aes-neonbs",
354*1abee99eSArd Biesheuvel 	.base.cra_priority	= 250,
355*1abee99eSArd Biesheuvel 	.base.cra_blocksize	= AES_BLOCK_SIZE,
356*1abee99eSArd Biesheuvel 	.base.cra_ctxsize	= sizeof(struct aesbs_xts_ctx),
357*1abee99eSArd Biesheuvel 	.base.cra_module	= THIS_MODULE,
358*1abee99eSArd Biesheuvel 	.base.cra_flags		= CRYPTO_ALG_INTERNAL,
359*1abee99eSArd Biesheuvel 
360*1abee99eSArd Biesheuvel 	.min_keysize		= 2 * AES_MIN_KEY_SIZE,
361*1abee99eSArd Biesheuvel 	.max_keysize		= 2 * AES_MAX_KEY_SIZE,
362*1abee99eSArd Biesheuvel 	.walksize		= 8 * AES_BLOCK_SIZE,
363*1abee99eSArd Biesheuvel 	.ivsize			= AES_BLOCK_SIZE,
364*1abee99eSArd Biesheuvel 	.setkey			= aesbs_xts_setkey,
365*1abee99eSArd Biesheuvel 	.encrypt		= xts_encrypt,
366*1abee99eSArd Biesheuvel 	.decrypt		= xts_decrypt,
367*1abee99eSArd Biesheuvel } };
368*1abee99eSArd Biesheuvel 
369*1abee99eSArd Biesheuvel static struct simd_skcipher_alg *aes_simd_algs[ARRAY_SIZE(aes_algs)];
370*1abee99eSArd Biesheuvel 
371*1abee99eSArd Biesheuvel static void aes_exit(void)
372*1abee99eSArd Biesheuvel {
373*1abee99eSArd Biesheuvel 	int i;
374*1abee99eSArd Biesheuvel 
375*1abee99eSArd Biesheuvel 	for (i = 0; i < ARRAY_SIZE(aes_simd_algs); i++)
376*1abee99eSArd Biesheuvel 		if (aes_simd_algs[i])
377*1abee99eSArd Biesheuvel 			simd_skcipher_free(aes_simd_algs[i]);
378*1abee99eSArd Biesheuvel 
379*1abee99eSArd Biesheuvel 	crypto_unregister_skciphers(aes_algs, ARRAY_SIZE(aes_algs));
380*1abee99eSArd Biesheuvel }
381*1abee99eSArd Biesheuvel 
382*1abee99eSArd Biesheuvel static int __init aes_init(void)
383*1abee99eSArd Biesheuvel {
384*1abee99eSArd Biesheuvel 	struct simd_skcipher_alg *simd;
385*1abee99eSArd Biesheuvel 	const char *basename;
386*1abee99eSArd Biesheuvel 	const char *algname;
387*1abee99eSArd Biesheuvel 	const char *drvname;
388*1abee99eSArd Biesheuvel 	int err;
389*1abee99eSArd Biesheuvel 	int i;
390*1abee99eSArd Biesheuvel 
391*1abee99eSArd Biesheuvel 	if (!(elf_hwcap & HWCAP_ASIMD))
392*1abee99eSArd Biesheuvel 		return -ENODEV;
393*1abee99eSArd Biesheuvel 
394*1abee99eSArd Biesheuvel 	err = crypto_register_skciphers(aes_algs, ARRAY_SIZE(aes_algs));
395*1abee99eSArd Biesheuvel 	if (err)
396*1abee99eSArd Biesheuvel 		return err;
397*1abee99eSArd Biesheuvel 
398*1abee99eSArd Biesheuvel 	for (i = 0; i < ARRAY_SIZE(aes_algs); i++) {
399*1abee99eSArd Biesheuvel 		if (!(aes_algs[i].base.cra_flags & CRYPTO_ALG_INTERNAL))
400*1abee99eSArd Biesheuvel 			continue;
401*1abee99eSArd Biesheuvel 
402*1abee99eSArd Biesheuvel 		algname = aes_algs[i].base.cra_name + 2;
403*1abee99eSArd Biesheuvel 		drvname = aes_algs[i].base.cra_driver_name + 2;
404*1abee99eSArd Biesheuvel 		basename = aes_algs[i].base.cra_driver_name;
405*1abee99eSArd Biesheuvel 		simd = simd_skcipher_create_compat(algname, drvname, basename);
406*1abee99eSArd Biesheuvel 		err = PTR_ERR(simd);
407*1abee99eSArd Biesheuvel 		if (IS_ERR(simd))
408*1abee99eSArd Biesheuvel 			goto unregister_simds;
409*1abee99eSArd Biesheuvel 
410*1abee99eSArd Biesheuvel 		aes_simd_algs[i] = simd;
411*1abee99eSArd Biesheuvel 	}
412*1abee99eSArd Biesheuvel 	return 0;
413*1abee99eSArd Biesheuvel 
414*1abee99eSArd Biesheuvel unregister_simds:
415*1abee99eSArd Biesheuvel 	aes_exit();
416*1abee99eSArd Biesheuvel 	return err;
417*1abee99eSArd Biesheuvel }
418*1abee99eSArd Biesheuvel 
419*1abee99eSArd Biesheuvel module_init(aes_init);
420*1abee99eSArd Biesheuvel module_exit(aes_exit);
421