xref: /linux/drivers/crypto/cavium/nitrox/nitrox_skcipher.c (revision c9613335bf4fe259a654aa0e9701f0c4cddc12ba)
1*c9613335SNagadheeraj Rottela // SPDX-License-Identifier: GPL-2.0
2*c9613335SNagadheeraj Rottela #include <linux/crypto.h>
3*c9613335SNagadheeraj Rottela #include <linux/kernel.h>
4*c9613335SNagadheeraj Rottela #include <linux/module.h>
5*c9613335SNagadheeraj Rottela #include <linux/printk.h>
6*c9613335SNagadheeraj Rottela 
7*c9613335SNagadheeraj Rottela #include <crypto/aes.h>
8*c9613335SNagadheeraj Rottela #include <crypto/skcipher.h>
9*c9613335SNagadheeraj Rottela #include <crypto/ctr.h>
10*c9613335SNagadheeraj Rottela #include <crypto/des.h>
11*c9613335SNagadheeraj Rottela #include <crypto/xts.h>
12*c9613335SNagadheeraj Rottela 
13*c9613335SNagadheeraj Rottela #include "nitrox_dev.h"
14*c9613335SNagadheeraj Rottela #include "nitrox_common.h"
15*c9613335SNagadheeraj Rottela #include "nitrox_req.h"
16*c9613335SNagadheeraj Rottela 
17*c9613335SNagadheeraj Rottela struct nitrox_cipher {
18*c9613335SNagadheeraj Rottela 	const char *name;
19*c9613335SNagadheeraj Rottela 	enum flexi_cipher value;
20*c9613335SNagadheeraj Rottela };
21*c9613335SNagadheeraj Rottela 
22*c9613335SNagadheeraj Rottela /**
23*c9613335SNagadheeraj Rottela  * supported cipher list
24*c9613335SNagadheeraj Rottela  */
25*c9613335SNagadheeraj Rottela static const struct nitrox_cipher flexi_cipher_table[] = {
26*c9613335SNagadheeraj Rottela 	{ "null",		CIPHER_NULL },
27*c9613335SNagadheeraj Rottela 	{ "cbc(des3_ede)",	CIPHER_3DES_CBC },
28*c9613335SNagadheeraj Rottela 	{ "ecb(des3_ede)",	CIPHER_3DES_ECB },
29*c9613335SNagadheeraj Rottela 	{ "cbc(aes)",		CIPHER_AES_CBC },
30*c9613335SNagadheeraj Rottela 	{ "ecb(aes)",		CIPHER_AES_ECB },
31*c9613335SNagadheeraj Rottela 	{ "cfb(aes)",		CIPHER_AES_CFB },
32*c9613335SNagadheeraj Rottela 	{ "rfc3686(ctr(aes))",	CIPHER_AES_CTR },
33*c9613335SNagadheeraj Rottela 	{ "xts(aes)",		CIPHER_AES_XTS },
34*c9613335SNagadheeraj Rottela 	{ "cts(cbc(aes))",	CIPHER_AES_CBC_CTS },
35*c9613335SNagadheeraj Rottela 	{ NULL,			CIPHER_INVALID }
36*c9613335SNagadheeraj Rottela };
37*c9613335SNagadheeraj Rottela 
38*c9613335SNagadheeraj Rottela static enum flexi_cipher flexi_cipher_type(const char *name)
39*c9613335SNagadheeraj Rottela {
40*c9613335SNagadheeraj Rottela 	const struct nitrox_cipher *cipher = flexi_cipher_table;
41*c9613335SNagadheeraj Rottela 
42*c9613335SNagadheeraj Rottela 	while (cipher->name) {
43*c9613335SNagadheeraj Rottela 		if (!strcmp(cipher->name, name))
44*c9613335SNagadheeraj Rottela 			break;
45*c9613335SNagadheeraj Rottela 		cipher++;
46*c9613335SNagadheeraj Rottela 	}
47*c9613335SNagadheeraj Rottela 	return cipher->value;
48*c9613335SNagadheeraj Rottela }
49*c9613335SNagadheeraj Rottela 
50*c9613335SNagadheeraj Rottela static int nitrox_skcipher_init(struct crypto_skcipher *tfm)
51*c9613335SNagadheeraj Rottela {
52*c9613335SNagadheeraj Rottela 	struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(tfm);
53*c9613335SNagadheeraj Rottela 	struct crypto_ctx_hdr *chdr;
54*c9613335SNagadheeraj Rottela 
55*c9613335SNagadheeraj Rottela 	/* get the first device */
56*c9613335SNagadheeraj Rottela 	nctx->ndev = nitrox_get_first_device();
57*c9613335SNagadheeraj Rottela 	if (!nctx->ndev)
58*c9613335SNagadheeraj Rottela 		return -ENODEV;
59*c9613335SNagadheeraj Rottela 
60*c9613335SNagadheeraj Rottela 	/* allocate nitrox crypto context */
61*c9613335SNagadheeraj Rottela 	chdr = crypto_alloc_context(nctx->ndev);
62*c9613335SNagadheeraj Rottela 	if (!chdr) {
63*c9613335SNagadheeraj Rottela 		nitrox_put_device(nctx->ndev);
64*c9613335SNagadheeraj Rottela 		return -ENOMEM;
65*c9613335SNagadheeraj Rottela 	}
66*c9613335SNagadheeraj Rottela 	nctx->chdr = chdr;
67*c9613335SNagadheeraj Rottela 	nctx->u.ctx_handle = (uintptr_t)((u8 *)chdr->vaddr +
68*c9613335SNagadheeraj Rottela 					 sizeof(struct ctx_hdr));
69*c9613335SNagadheeraj Rottela 	crypto_skcipher_set_reqsize(tfm, crypto_skcipher_reqsize(tfm) +
70*c9613335SNagadheeraj Rottela 				    sizeof(struct nitrox_kcrypt_request));
71*c9613335SNagadheeraj Rottela 	return 0;
72*c9613335SNagadheeraj Rottela }
73*c9613335SNagadheeraj Rottela 
74*c9613335SNagadheeraj Rottela static void nitrox_skcipher_exit(struct crypto_skcipher *tfm)
75*c9613335SNagadheeraj Rottela {
76*c9613335SNagadheeraj Rottela 	struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(tfm);
77*c9613335SNagadheeraj Rottela 
78*c9613335SNagadheeraj Rottela 	/* free the nitrox crypto context */
79*c9613335SNagadheeraj Rottela 	if (nctx->u.ctx_handle) {
80*c9613335SNagadheeraj Rottela 		struct flexi_crypto_context *fctx = nctx->u.fctx;
81*c9613335SNagadheeraj Rottela 
82*c9613335SNagadheeraj Rottela 		memzero_explicit(&fctx->crypto, sizeof(struct crypto_keys));
83*c9613335SNagadheeraj Rottela 		memzero_explicit(&fctx->auth, sizeof(struct auth_keys));
84*c9613335SNagadheeraj Rottela 		crypto_free_context((void *)nctx->chdr);
85*c9613335SNagadheeraj Rottela 	}
86*c9613335SNagadheeraj Rottela 	nitrox_put_device(nctx->ndev);
87*c9613335SNagadheeraj Rottela 
88*c9613335SNagadheeraj Rottela 	nctx->u.ctx_handle = 0;
89*c9613335SNagadheeraj Rottela 	nctx->ndev = NULL;
90*c9613335SNagadheeraj Rottela }
91*c9613335SNagadheeraj Rottela 
92*c9613335SNagadheeraj Rottela static inline int nitrox_skcipher_setkey(struct crypto_skcipher *cipher,
93*c9613335SNagadheeraj Rottela 					 int aes_keylen, const u8 *key,
94*c9613335SNagadheeraj Rottela 					 unsigned int keylen)
95*c9613335SNagadheeraj Rottela {
96*c9613335SNagadheeraj Rottela 	struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher);
97*c9613335SNagadheeraj Rottela 	struct nitrox_crypto_ctx *nctx = crypto_tfm_ctx(tfm);
98*c9613335SNagadheeraj Rottela 	struct flexi_crypto_context *fctx;
99*c9613335SNagadheeraj Rottela 	union fc_ctx_flags *flags;
100*c9613335SNagadheeraj Rottela 	enum flexi_cipher cipher_type;
101*c9613335SNagadheeraj Rottela 	const char *name;
102*c9613335SNagadheeraj Rottela 
103*c9613335SNagadheeraj Rottela 	name = crypto_tfm_alg_name(tfm);
104*c9613335SNagadheeraj Rottela 	cipher_type = flexi_cipher_type(name);
105*c9613335SNagadheeraj Rottela 	if (unlikely(cipher_type == CIPHER_INVALID)) {
106*c9613335SNagadheeraj Rottela 		pr_err("unsupported cipher: %s\n", name);
107*c9613335SNagadheeraj Rottela 		return -EINVAL;
108*c9613335SNagadheeraj Rottela 	}
109*c9613335SNagadheeraj Rottela 
110*c9613335SNagadheeraj Rottela 	/* fill crypto context */
111*c9613335SNagadheeraj Rottela 	fctx = nctx->u.fctx;
112*c9613335SNagadheeraj Rottela 	flags = &fctx->flags;
113*c9613335SNagadheeraj Rottela 	flags->f = 0;
114*c9613335SNagadheeraj Rottela 	flags->w0.cipher_type = cipher_type;
115*c9613335SNagadheeraj Rottela 	flags->w0.aes_keylen = aes_keylen;
116*c9613335SNagadheeraj Rottela 	flags->w0.iv_source = IV_FROM_DPTR;
117*c9613335SNagadheeraj Rottela 	flags->f = cpu_to_be64(*(u64 *)&flags->w0);
118*c9613335SNagadheeraj Rottela 	/* copy the key to context */
119*c9613335SNagadheeraj Rottela 	memcpy(fctx->crypto.u.key, key, keylen);
120*c9613335SNagadheeraj Rottela 
121*c9613335SNagadheeraj Rottela 	return 0;
122*c9613335SNagadheeraj Rottela }
123*c9613335SNagadheeraj Rottela 
124*c9613335SNagadheeraj Rottela static int nitrox_aes_setkey(struct crypto_skcipher *cipher, const u8 *key,
125*c9613335SNagadheeraj Rottela 			     unsigned int keylen)
126*c9613335SNagadheeraj Rottela {
127*c9613335SNagadheeraj Rottela 	int aes_keylen;
128*c9613335SNagadheeraj Rottela 
129*c9613335SNagadheeraj Rottela 	aes_keylen = flexi_aes_keylen(keylen);
130*c9613335SNagadheeraj Rottela 	if (aes_keylen < 0) {
131*c9613335SNagadheeraj Rottela 		crypto_skcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
132*c9613335SNagadheeraj Rottela 		return -EINVAL;
133*c9613335SNagadheeraj Rottela 	}
134*c9613335SNagadheeraj Rottela 	return nitrox_skcipher_setkey(cipher, aes_keylen, key, keylen);
135*c9613335SNagadheeraj Rottela }
136*c9613335SNagadheeraj Rottela 
137*c9613335SNagadheeraj Rottela static int alloc_src_sglist(struct skcipher_request *skreq, int ivsize)
138*c9613335SNagadheeraj Rottela {
139*c9613335SNagadheeraj Rottela 	struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
140*c9613335SNagadheeraj Rottela 	int nents = sg_nents(skreq->src) + 1;
141*c9613335SNagadheeraj Rottela 	int ret;
142*c9613335SNagadheeraj Rottela 
143*c9613335SNagadheeraj Rottela 	/* Allocate buffer to hold IV and input scatterlist array */
144*c9613335SNagadheeraj Rottela 	ret = alloc_src_req_buf(nkreq, nents, ivsize);
145*c9613335SNagadheeraj Rottela 	if (ret)
146*c9613335SNagadheeraj Rottela 		return ret;
147*c9613335SNagadheeraj Rottela 
148*c9613335SNagadheeraj Rottela 	nitrox_creq_copy_iv(nkreq->src, skreq->iv, ivsize);
149*c9613335SNagadheeraj Rottela 	nitrox_creq_set_src_sg(nkreq, nents, ivsize, skreq->src,
150*c9613335SNagadheeraj Rottela 			       skreq->cryptlen);
151*c9613335SNagadheeraj Rottela 
152*c9613335SNagadheeraj Rottela 	return 0;
153*c9613335SNagadheeraj Rottela }
154*c9613335SNagadheeraj Rottela 
155*c9613335SNagadheeraj Rottela static int alloc_dst_sglist(struct skcipher_request *skreq, int ivsize)
156*c9613335SNagadheeraj Rottela {
157*c9613335SNagadheeraj Rottela 	struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
158*c9613335SNagadheeraj Rottela 	int nents = sg_nents(skreq->dst) + 3;
159*c9613335SNagadheeraj Rottela 	int ret;
160*c9613335SNagadheeraj Rottela 
161*c9613335SNagadheeraj Rottela 	/* Allocate buffer to hold ORH, COMPLETION and output scatterlist
162*c9613335SNagadheeraj Rottela 	 * array
163*c9613335SNagadheeraj Rottela 	 */
164*c9613335SNagadheeraj Rottela 	ret = alloc_dst_req_buf(nkreq, nents);
165*c9613335SNagadheeraj Rottela 	if (ret)
166*c9613335SNagadheeraj Rottela 		return ret;
167*c9613335SNagadheeraj Rottela 
168*c9613335SNagadheeraj Rottela 	nitrox_creq_set_orh(nkreq);
169*c9613335SNagadheeraj Rottela 	nitrox_creq_set_comp(nkreq);
170*c9613335SNagadheeraj Rottela 	nitrox_creq_set_dst_sg(nkreq, nents, ivsize, skreq->dst,
171*c9613335SNagadheeraj Rottela 			       skreq->cryptlen);
172*c9613335SNagadheeraj Rottela 
173*c9613335SNagadheeraj Rottela 	return 0;
174*c9613335SNagadheeraj Rottela }
175*c9613335SNagadheeraj Rottela 
176*c9613335SNagadheeraj Rottela static void free_src_sglist(struct skcipher_request *skreq)
177*c9613335SNagadheeraj Rottela {
178*c9613335SNagadheeraj Rottela 	struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
179*c9613335SNagadheeraj Rottela 
180*c9613335SNagadheeraj Rottela 	kfree(nkreq->src);
181*c9613335SNagadheeraj Rottela }
182*c9613335SNagadheeraj Rottela 
183*c9613335SNagadheeraj Rottela static void free_dst_sglist(struct skcipher_request *skreq)
184*c9613335SNagadheeraj Rottela {
185*c9613335SNagadheeraj Rottela 	struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
186*c9613335SNagadheeraj Rottela 
187*c9613335SNagadheeraj Rottela 	kfree(nkreq->dst);
188*c9613335SNagadheeraj Rottela }
189*c9613335SNagadheeraj Rottela 
190*c9613335SNagadheeraj Rottela static void nitrox_skcipher_callback(void *arg, int err)
191*c9613335SNagadheeraj Rottela {
192*c9613335SNagadheeraj Rottela 	struct skcipher_request *skreq = arg;
193*c9613335SNagadheeraj Rottela 
194*c9613335SNagadheeraj Rottela 	free_src_sglist(skreq);
195*c9613335SNagadheeraj Rottela 	free_dst_sglist(skreq);
196*c9613335SNagadheeraj Rottela 	if (err) {
197*c9613335SNagadheeraj Rottela 		pr_err_ratelimited("request failed status 0x%0x\n", err);
198*c9613335SNagadheeraj Rottela 		err = -EINVAL;
199*c9613335SNagadheeraj Rottela 	}
200*c9613335SNagadheeraj Rottela 
201*c9613335SNagadheeraj Rottela 	skcipher_request_complete(skreq, err);
202*c9613335SNagadheeraj Rottela }
203*c9613335SNagadheeraj Rottela 
204*c9613335SNagadheeraj Rottela static int nitrox_skcipher_crypt(struct skcipher_request *skreq, bool enc)
205*c9613335SNagadheeraj Rottela {
206*c9613335SNagadheeraj Rottela 	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(skreq);
207*c9613335SNagadheeraj Rottela 	struct nitrox_crypto_ctx *nctx = crypto_skcipher_ctx(cipher);
208*c9613335SNagadheeraj Rottela 	struct nitrox_kcrypt_request *nkreq = skcipher_request_ctx(skreq);
209*c9613335SNagadheeraj Rottela 	int ivsize = crypto_skcipher_ivsize(cipher);
210*c9613335SNagadheeraj Rottela 	struct se_crypto_request *creq;
211*c9613335SNagadheeraj Rottela 	int ret;
212*c9613335SNagadheeraj Rottela 
213*c9613335SNagadheeraj Rottela 	creq = &nkreq->creq;
214*c9613335SNagadheeraj Rottela 	creq->flags = skreq->base.flags;
215*c9613335SNagadheeraj Rottela 	creq->gfp = (skreq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
216*c9613335SNagadheeraj Rottela 		     GFP_KERNEL : GFP_ATOMIC;
217*c9613335SNagadheeraj Rottela 
218*c9613335SNagadheeraj Rottela 	/* fill the request */
219*c9613335SNagadheeraj Rottela 	creq->ctrl.value = 0;
220*c9613335SNagadheeraj Rottela 	creq->opcode = FLEXI_CRYPTO_ENCRYPT_HMAC;
221*c9613335SNagadheeraj Rottela 	creq->ctrl.s.arg = (enc ? ENCRYPT : DECRYPT);
222*c9613335SNagadheeraj Rottela 	/* param0: length of the data to be encrypted */
223*c9613335SNagadheeraj Rottela 	creq->gph.param0 = cpu_to_be16(skreq->cryptlen);
224*c9613335SNagadheeraj Rottela 	creq->gph.param1 = 0;
225*c9613335SNagadheeraj Rottela 	/* param2: encryption data offset */
226*c9613335SNagadheeraj Rottela 	creq->gph.param2 = cpu_to_be16(ivsize);
227*c9613335SNagadheeraj Rottela 	creq->gph.param3 = 0;
228*c9613335SNagadheeraj Rottela 
229*c9613335SNagadheeraj Rottela 	creq->ctx_handle = nctx->u.ctx_handle;
230*c9613335SNagadheeraj Rottela 	creq->ctrl.s.ctxl = sizeof(struct flexi_crypto_context);
231*c9613335SNagadheeraj Rottela 
232*c9613335SNagadheeraj Rottela 	ret = alloc_src_sglist(skreq, ivsize);
233*c9613335SNagadheeraj Rottela 	if (ret)
234*c9613335SNagadheeraj Rottela 		return ret;
235*c9613335SNagadheeraj Rottela 
236*c9613335SNagadheeraj Rottela 	ret = alloc_dst_sglist(skreq, ivsize);
237*c9613335SNagadheeraj Rottela 	if (ret) {
238*c9613335SNagadheeraj Rottela 		free_src_sglist(skreq);
239*c9613335SNagadheeraj Rottela 		return ret;
240*c9613335SNagadheeraj Rottela 	}
241*c9613335SNagadheeraj Rottela 
242*c9613335SNagadheeraj Rottela 	/* send the crypto request */
243*c9613335SNagadheeraj Rottela 	return nitrox_process_se_request(nctx->ndev, creq,
244*c9613335SNagadheeraj Rottela 					 nitrox_skcipher_callback, skreq);
245*c9613335SNagadheeraj Rottela }
246*c9613335SNagadheeraj Rottela 
247*c9613335SNagadheeraj Rottela static int nitrox_aes_encrypt(struct skcipher_request *skreq)
248*c9613335SNagadheeraj Rottela {
249*c9613335SNagadheeraj Rottela 	return nitrox_skcipher_crypt(skreq, true);
250*c9613335SNagadheeraj Rottela }
251*c9613335SNagadheeraj Rottela 
252*c9613335SNagadheeraj Rottela static int nitrox_aes_decrypt(struct skcipher_request *skreq)
253*c9613335SNagadheeraj Rottela {
254*c9613335SNagadheeraj Rottela 	return nitrox_skcipher_crypt(skreq, false);
255*c9613335SNagadheeraj Rottela }
256*c9613335SNagadheeraj Rottela 
257*c9613335SNagadheeraj Rottela static int nitrox_3des_setkey(struct crypto_skcipher *cipher,
258*c9613335SNagadheeraj Rottela 			      const u8 *key, unsigned int keylen)
259*c9613335SNagadheeraj Rottela {
260*c9613335SNagadheeraj Rottela 	if (keylen != DES3_EDE_KEY_SIZE) {
261*c9613335SNagadheeraj Rottela 		crypto_skcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
262*c9613335SNagadheeraj Rottela 		return -EINVAL;
263*c9613335SNagadheeraj Rottela 	}
264*c9613335SNagadheeraj Rottela 
265*c9613335SNagadheeraj Rottela 	return nitrox_skcipher_setkey(cipher, 0, key, keylen);
266*c9613335SNagadheeraj Rottela }
267*c9613335SNagadheeraj Rottela 
268*c9613335SNagadheeraj Rottela static int nitrox_3des_encrypt(struct skcipher_request *skreq)
269*c9613335SNagadheeraj Rottela {
270*c9613335SNagadheeraj Rottela 	return nitrox_skcipher_crypt(skreq, true);
271*c9613335SNagadheeraj Rottela }
272*c9613335SNagadheeraj Rottela 
273*c9613335SNagadheeraj Rottela static int nitrox_3des_decrypt(struct skcipher_request *skreq)
274*c9613335SNagadheeraj Rottela {
275*c9613335SNagadheeraj Rottela 	return nitrox_skcipher_crypt(skreq, false);
276*c9613335SNagadheeraj Rottela }
277*c9613335SNagadheeraj Rottela 
278*c9613335SNagadheeraj Rottela static int nitrox_aes_xts_setkey(struct crypto_skcipher *cipher,
279*c9613335SNagadheeraj Rottela 				 const u8 *key, unsigned int keylen)
280*c9613335SNagadheeraj Rottela {
281*c9613335SNagadheeraj Rottela 	struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher);
282*c9613335SNagadheeraj Rottela 	struct nitrox_crypto_ctx *nctx = crypto_tfm_ctx(tfm);
283*c9613335SNagadheeraj Rottela 	struct flexi_crypto_context *fctx;
284*c9613335SNagadheeraj Rottela 	int aes_keylen, ret;
285*c9613335SNagadheeraj Rottela 
286*c9613335SNagadheeraj Rottela 	ret = xts_check_key(tfm, key, keylen);
287*c9613335SNagadheeraj Rottela 	if (ret)
288*c9613335SNagadheeraj Rottela 		return ret;
289*c9613335SNagadheeraj Rottela 
290*c9613335SNagadheeraj Rottela 	keylen /= 2;
291*c9613335SNagadheeraj Rottela 
292*c9613335SNagadheeraj Rottela 	aes_keylen = flexi_aes_keylen(keylen);
293*c9613335SNagadheeraj Rottela 	if (aes_keylen < 0) {
294*c9613335SNagadheeraj Rottela 		crypto_skcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
295*c9613335SNagadheeraj Rottela 		return -EINVAL;
296*c9613335SNagadheeraj Rottela 	}
297*c9613335SNagadheeraj Rottela 
298*c9613335SNagadheeraj Rottela 	fctx = nctx->u.fctx;
299*c9613335SNagadheeraj Rottela 	/* copy KEY2 */
300*c9613335SNagadheeraj Rottela 	memcpy(fctx->auth.u.key2, (key + keylen), keylen);
301*c9613335SNagadheeraj Rottela 
302*c9613335SNagadheeraj Rottela 	return nitrox_skcipher_setkey(cipher, aes_keylen, key, keylen);
303*c9613335SNagadheeraj Rottela }
304*c9613335SNagadheeraj Rottela 
305*c9613335SNagadheeraj Rottela static int nitrox_aes_ctr_rfc3686_setkey(struct crypto_skcipher *cipher,
306*c9613335SNagadheeraj Rottela 					 const u8 *key, unsigned int keylen)
307*c9613335SNagadheeraj Rottela {
308*c9613335SNagadheeraj Rottela 	struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher);
309*c9613335SNagadheeraj Rottela 	struct nitrox_crypto_ctx *nctx = crypto_tfm_ctx(tfm);
310*c9613335SNagadheeraj Rottela 	struct flexi_crypto_context *fctx;
311*c9613335SNagadheeraj Rottela 	int aes_keylen;
312*c9613335SNagadheeraj Rottela 
313*c9613335SNagadheeraj Rottela 	if (keylen < CTR_RFC3686_NONCE_SIZE)
314*c9613335SNagadheeraj Rottela 		return -EINVAL;
315*c9613335SNagadheeraj Rottela 
316*c9613335SNagadheeraj Rottela 	fctx = nctx->u.fctx;
317*c9613335SNagadheeraj Rottela 
318*c9613335SNagadheeraj Rottela 	memcpy(fctx->crypto.iv, key + (keylen - CTR_RFC3686_NONCE_SIZE),
319*c9613335SNagadheeraj Rottela 	       CTR_RFC3686_NONCE_SIZE);
320*c9613335SNagadheeraj Rottela 
321*c9613335SNagadheeraj Rottela 	keylen -= CTR_RFC3686_NONCE_SIZE;
322*c9613335SNagadheeraj Rottela 
323*c9613335SNagadheeraj Rottela 	aes_keylen = flexi_aes_keylen(keylen);
324*c9613335SNagadheeraj Rottela 	if (aes_keylen < 0) {
325*c9613335SNagadheeraj Rottela 		crypto_skcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
326*c9613335SNagadheeraj Rottela 		return -EINVAL;
327*c9613335SNagadheeraj Rottela 	}
328*c9613335SNagadheeraj Rottela 	return nitrox_skcipher_setkey(cipher, aes_keylen, key, keylen);
329*c9613335SNagadheeraj Rottela }
330*c9613335SNagadheeraj Rottela 
331*c9613335SNagadheeraj Rottela static struct skcipher_alg nitrox_skciphers[] = { {
332*c9613335SNagadheeraj Rottela 	.base = {
333*c9613335SNagadheeraj Rottela 		.cra_name = "cbc(aes)",
334*c9613335SNagadheeraj Rottela 		.cra_driver_name = "n5_cbc(aes)",
335*c9613335SNagadheeraj Rottela 		.cra_priority = PRIO,
336*c9613335SNagadheeraj Rottela 		.cra_flags = CRYPTO_ALG_ASYNC,
337*c9613335SNagadheeraj Rottela 		.cra_blocksize = AES_BLOCK_SIZE,
338*c9613335SNagadheeraj Rottela 		.cra_ctxsize = sizeof(struct nitrox_crypto_ctx),
339*c9613335SNagadheeraj Rottela 		.cra_alignmask = 0,
340*c9613335SNagadheeraj Rottela 		.cra_module = THIS_MODULE,
341*c9613335SNagadheeraj Rottela 	},
342*c9613335SNagadheeraj Rottela 	.min_keysize = AES_MIN_KEY_SIZE,
343*c9613335SNagadheeraj Rottela 	.max_keysize = AES_MAX_KEY_SIZE,
344*c9613335SNagadheeraj Rottela 	.ivsize = AES_BLOCK_SIZE,
345*c9613335SNagadheeraj Rottela 	.setkey = nitrox_aes_setkey,
346*c9613335SNagadheeraj Rottela 	.encrypt = nitrox_aes_encrypt,
347*c9613335SNagadheeraj Rottela 	.decrypt = nitrox_aes_decrypt,
348*c9613335SNagadheeraj Rottela 	.init = nitrox_skcipher_init,
349*c9613335SNagadheeraj Rottela 	.exit = nitrox_skcipher_exit,
350*c9613335SNagadheeraj Rottela }, {
351*c9613335SNagadheeraj Rottela 	.base = {
352*c9613335SNagadheeraj Rottela 		.cra_name = "ecb(aes)",
353*c9613335SNagadheeraj Rottela 		.cra_driver_name = "n5_ecb(aes)",
354*c9613335SNagadheeraj Rottela 		.cra_priority = PRIO,
355*c9613335SNagadheeraj Rottela 		.cra_flags = CRYPTO_ALG_ASYNC,
356*c9613335SNagadheeraj Rottela 		.cra_blocksize = AES_BLOCK_SIZE,
357*c9613335SNagadheeraj Rottela 		.cra_ctxsize = sizeof(struct nitrox_crypto_ctx),
358*c9613335SNagadheeraj Rottela 		.cra_alignmask = 0,
359*c9613335SNagadheeraj Rottela 		.cra_module = THIS_MODULE,
360*c9613335SNagadheeraj Rottela 	},
361*c9613335SNagadheeraj Rottela 	.min_keysize = AES_MIN_KEY_SIZE,
362*c9613335SNagadheeraj Rottela 	.max_keysize = AES_MAX_KEY_SIZE,
363*c9613335SNagadheeraj Rottela 	.ivsize = AES_BLOCK_SIZE,
364*c9613335SNagadheeraj Rottela 	.setkey = nitrox_aes_setkey,
365*c9613335SNagadheeraj Rottela 	.encrypt = nitrox_aes_encrypt,
366*c9613335SNagadheeraj Rottela 	.decrypt = nitrox_aes_decrypt,
367*c9613335SNagadheeraj Rottela 	.init = nitrox_skcipher_init,
368*c9613335SNagadheeraj Rottela 	.exit = nitrox_skcipher_exit,
369*c9613335SNagadheeraj Rottela }, {
370*c9613335SNagadheeraj Rottela 	.base = {
371*c9613335SNagadheeraj Rottela 		.cra_name = "cfb(aes)",
372*c9613335SNagadheeraj Rottela 		.cra_driver_name = "n5_cfb(aes)",
373*c9613335SNagadheeraj Rottela 		.cra_priority = PRIO,
374*c9613335SNagadheeraj Rottela 		.cra_flags = CRYPTO_ALG_ASYNC,
375*c9613335SNagadheeraj Rottela 		.cra_blocksize = AES_BLOCK_SIZE,
376*c9613335SNagadheeraj Rottela 		.cra_ctxsize = sizeof(struct nitrox_crypto_ctx),
377*c9613335SNagadheeraj Rottela 		.cra_alignmask = 0,
378*c9613335SNagadheeraj Rottela 		.cra_module = THIS_MODULE,
379*c9613335SNagadheeraj Rottela 	},
380*c9613335SNagadheeraj Rottela 	.min_keysize = AES_MIN_KEY_SIZE,
381*c9613335SNagadheeraj Rottela 	.max_keysize = AES_MAX_KEY_SIZE,
382*c9613335SNagadheeraj Rottela 	.ivsize = AES_BLOCK_SIZE,
383*c9613335SNagadheeraj Rottela 	.setkey = nitrox_aes_setkey,
384*c9613335SNagadheeraj Rottela 	.encrypt = nitrox_aes_encrypt,
385*c9613335SNagadheeraj Rottela 	.decrypt = nitrox_aes_decrypt,
386*c9613335SNagadheeraj Rottela 	.init = nitrox_skcipher_init,
387*c9613335SNagadheeraj Rottela 	.exit = nitrox_skcipher_exit,
388*c9613335SNagadheeraj Rottela }, {
389*c9613335SNagadheeraj Rottela 	.base = {
390*c9613335SNagadheeraj Rottela 		.cra_name = "xts(aes)",
391*c9613335SNagadheeraj Rottela 		.cra_driver_name = "n5_xts(aes)",
392*c9613335SNagadheeraj Rottela 		.cra_priority = PRIO,
393*c9613335SNagadheeraj Rottela 		.cra_flags = CRYPTO_ALG_ASYNC,
394*c9613335SNagadheeraj Rottela 		.cra_blocksize = AES_BLOCK_SIZE,
395*c9613335SNagadheeraj Rottela 		.cra_ctxsize = sizeof(struct nitrox_crypto_ctx),
396*c9613335SNagadheeraj Rottela 		.cra_alignmask = 0,
397*c9613335SNagadheeraj Rottela 		.cra_module = THIS_MODULE,
398*c9613335SNagadheeraj Rottela 	},
399*c9613335SNagadheeraj Rottela 	.min_keysize = 2 * AES_MIN_KEY_SIZE,
400*c9613335SNagadheeraj Rottela 	.max_keysize = 2 * AES_MAX_KEY_SIZE,
401*c9613335SNagadheeraj Rottela 	.ivsize = AES_BLOCK_SIZE,
402*c9613335SNagadheeraj Rottela 	.setkey = nitrox_aes_xts_setkey,
403*c9613335SNagadheeraj Rottela 	.encrypt = nitrox_aes_encrypt,
404*c9613335SNagadheeraj Rottela 	.decrypt = nitrox_aes_decrypt,
405*c9613335SNagadheeraj Rottela 	.init = nitrox_skcipher_init,
406*c9613335SNagadheeraj Rottela 	.exit = nitrox_skcipher_exit,
407*c9613335SNagadheeraj Rottela }, {
408*c9613335SNagadheeraj Rottela 	.base = {
409*c9613335SNagadheeraj Rottela 		.cra_name = "rfc3686(ctr(aes))",
410*c9613335SNagadheeraj Rottela 		.cra_driver_name = "n5_rfc3686(ctr(aes))",
411*c9613335SNagadheeraj Rottela 		.cra_priority = PRIO,
412*c9613335SNagadheeraj Rottela 		.cra_flags = CRYPTO_ALG_ASYNC,
413*c9613335SNagadheeraj Rottela 		.cra_blocksize = 1,
414*c9613335SNagadheeraj Rottela 		.cra_ctxsize = sizeof(struct nitrox_crypto_ctx),
415*c9613335SNagadheeraj Rottela 		.cra_alignmask = 0,
416*c9613335SNagadheeraj Rottela 		.cra_module = THIS_MODULE,
417*c9613335SNagadheeraj Rottela 	},
418*c9613335SNagadheeraj Rottela 	.min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,
419*c9613335SNagadheeraj Rottela 	.max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,
420*c9613335SNagadheeraj Rottela 	.ivsize = CTR_RFC3686_IV_SIZE,
421*c9613335SNagadheeraj Rottela 	.init = nitrox_skcipher_init,
422*c9613335SNagadheeraj Rottela 	.exit = nitrox_skcipher_exit,
423*c9613335SNagadheeraj Rottela 	.setkey = nitrox_aes_ctr_rfc3686_setkey,
424*c9613335SNagadheeraj Rottela 	.encrypt = nitrox_aes_encrypt,
425*c9613335SNagadheeraj Rottela 	.decrypt = nitrox_aes_decrypt,
426*c9613335SNagadheeraj Rottela }, {
427*c9613335SNagadheeraj Rottela 	.base = {
428*c9613335SNagadheeraj Rottela 		.cra_name = "cts(cbc(aes))",
429*c9613335SNagadheeraj Rottela 		.cra_driver_name = "n5_cts(cbc(aes))",
430*c9613335SNagadheeraj Rottela 		.cra_priority = PRIO,
431*c9613335SNagadheeraj Rottela 		.cra_flags = CRYPTO_ALG_ASYNC,
432*c9613335SNagadheeraj Rottela 		.cra_blocksize = AES_BLOCK_SIZE,
433*c9613335SNagadheeraj Rottela 		.cra_ctxsize = sizeof(struct nitrox_crypto_ctx),
434*c9613335SNagadheeraj Rottela 		.cra_alignmask = 0,
435*c9613335SNagadheeraj Rottela 		.cra_type = &crypto_ablkcipher_type,
436*c9613335SNagadheeraj Rottela 		.cra_module = THIS_MODULE,
437*c9613335SNagadheeraj Rottela 	},
438*c9613335SNagadheeraj Rottela 	.min_keysize = AES_MIN_KEY_SIZE,
439*c9613335SNagadheeraj Rottela 	.max_keysize = AES_MAX_KEY_SIZE,
440*c9613335SNagadheeraj Rottela 	.ivsize = AES_BLOCK_SIZE,
441*c9613335SNagadheeraj Rottela 	.setkey = nitrox_aes_setkey,
442*c9613335SNagadheeraj Rottela 	.encrypt = nitrox_aes_encrypt,
443*c9613335SNagadheeraj Rottela 	.decrypt = nitrox_aes_decrypt,
444*c9613335SNagadheeraj Rottela 	.init = nitrox_skcipher_init,
445*c9613335SNagadheeraj Rottela 	.exit = nitrox_skcipher_exit,
446*c9613335SNagadheeraj Rottela }, {
447*c9613335SNagadheeraj Rottela 	.base = {
448*c9613335SNagadheeraj Rottela 		.cra_name = "cbc(des3_ede)",
449*c9613335SNagadheeraj Rottela 		.cra_driver_name = "n5_cbc(des3_ede)",
450*c9613335SNagadheeraj Rottela 		.cra_priority = PRIO,
451*c9613335SNagadheeraj Rottela 		.cra_flags = CRYPTO_ALG_ASYNC,
452*c9613335SNagadheeraj Rottela 		.cra_blocksize = DES3_EDE_BLOCK_SIZE,
453*c9613335SNagadheeraj Rottela 		.cra_ctxsize = sizeof(struct nitrox_crypto_ctx),
454*c9613335SNagadheeraj Rottela 		.cra_alignmask = 0,
455*c9613335SNagadheeraj Rottela 		.cra_module = THIS_MODULE,
456*c9613335SNagadheeraj Rottela 	},
457*c9613335SNagadheeraj Rottela 	.min_keysize = DES3_EDE_KEY_SIZE,
458*c9613335SNagadheeraj Rottela 	.max_keysize = DES3_EDE_KEY_SIZE,
459*c9613335SNagadheeraj Rottela 	.ivsize = DES3_EDE_BLOCK_SIZE,
460*c9613335SNagadheeraj Rottela 	.setkey = nitrox_3des_setkey,
461*c9613335SNagadheeraj Rottela 	.encrypt = nitrox_3des_encrypt,
462*c9613335SNagadheeraj Rottela 	.decrypt = nitrox_3des_decrypt,
463*c9613335SNagadheeraj Rottela 	.init = nitrox_skcipher_init,
464*c9613335SNagadheeraj Rottela 	.exit = nitrox_skcipher_exit,
465*c9613335SNagadheeraj Rottela }, {
466*c9613335SNagadheeraj Rottela 	.base = {
467*c9613335SNagadheeraj Rottela 		.cra_name = "ecb(des3_ede)",
468*c9613335SNagadheeraj Rottela 		.cra_driver_name = "n5_ecb(des3_ede)",
469*c9613335SNagadheeraj Rottela 		.cra_priority = PRIO,
470*c9613335SNagadheeraj Rottela 		.cra_flags = CRYPTO_ALG_ASYNC,
471*c9613335SNagadheeraj Rottela 		.cra_blocksize = DES3_EDE_BLOCK_SIZE,
472*c9613335SNagadheeraj Rottela 		.cra_ctxsize = sizeof(struct nitrox_crypto_ctx),
473*c9613335SNagadheeraj Rottela 		.cra_alignmask = 0,
474*c9613335SNagadheeraj Rottela 		.cra_module = THIS_MODULE,
475*c9613335SNagadheeraj Rottela 	},
476*c9613335SNagadheeraj Rottela 	.min_keysize = DES3_EDE_KEY_SIZE,
477*c9613335SNagadheeraj Rottela 	.max_keysize = DES3_EDE_KEY_SIZE,
478*c9613335SNagadheeraj Rottela 	.ivsize = DES3_EDE_BLOCK_SIZE,
479*c9613335SNagadheeraj Rottela 	.setkey = nitrox_3des_setkey,
480*c9613335SNagadheeraj Rottela 	.encrypt = nitrox_3des_encrypt,
481*c9613335SNagadheeraj Rottela 	.decrypt = nitrox_3des_decrypt,
482*c9613335SNagadheeraj Rottela 	.init = nitrox_skcipher_init,
483*c9613335SNagadheeraj Rottela 	.exit = nitrox_skcipher_exit,
484*c9613335SNagadheeraj Rottela }
485*c9613335SNagadheeraj Rottela 
486*c9613335SNagadheeraj Rottela };
487*c9613335SNagadheeraj Rottela 
488*c9613335SNagadheeraj Rottela int nitrox_register_skciphers(void)
489*c9613335SNagadheeraj Rottela {
490*c9613335SNagadheeraj Rottela 	return crypto_register_skciphers(nitrox_skciphers,
491*c9613335SNagadheeraj Rottela 					 ARRAY_SIZE(nitrox_skciphers));
492*c9613335SNagadheeraj Rottela }
493*c9613335SNagadheeraj Rottela 
494*c9613335SNagadheeraj Rottela void nitrox_unregister_skciphers(void)
495*c9613335SNagadheeraj Rottela {
496*c9613335SNagadheeraj Rottela 	crypto_unregister_skciphers(nitrox_skciphers,
497*c9613335SNagadheeraj Rottela 				    ARRAY_SIZE(nitrox_skciphers));
498*c9613335SNagadheeraj Rottela }
499