xref: /openbmc/linux/drivers/crypto/rockchip/rk3288_crypto_skcipher.c (revision 0c3dc787a62aef3ca7aedf3797ec42fff9b0a913)
1ce0183cbSArd Biesheuvel // SPDX-License-Identifier: GPL-2.0-only
2ce0183cbSArd Biesheuvel /*
3ce0183cbSArd Biesheuvel  * Crypto acceleration support for Rockchip RK3288
4ce0183cbSArd Biesheuvel  *
5ce0183cbSArd Biesheuvel  * Copyright (c) 2015, Fuzhou Rockchip Electronics Co., Ltd
6ce0183cbSArd Biesheuvel  *
7ce0183cbSArd Biesheuvel  * Author: Zain Wang <zain.wang@rock-chips.com>
8ce0183cbSArd Biesheuvel  *
9ce0183cbSArd Biesheuvel  * Some ideas are from marvell-cesa.c and s5p-sss.c driver.
10ce0183cbSArd Biesheuvel  */
11*0c3dc787SHerbert Xu #include <linux/device.h>
12ce0183cbSArd Biesheuvel #include "rk3288_crypto.h"
13ce0183cbSArd Biesheuvel 
14ce0183cbSArd Biesheuvel #define RK_CRYPTO_DEC			BIT(0)
15ce0183cbSArd Biesheuvel 
16ce0183cbSArd Biesheuvel static void rk_crypto_complete(struct crypto_async_request *base, int err)
17ce0183cbSArd Biesheuvel {
18ce0183cbSArd Biesheuvel 	if (base->complete)
19ce0183cbSArd Biesheuvel 		base->complete(base, err);
20ce0183cbSArd Biesheuvel }
21ce0183cbSArd Biesheuvel 
22ce0183cbSArd Biesheuvel static int rk_handle_req(struct rk_crypto_info *dev,
23ce0183cbSArd Biesheuvel 			 struct skcipher_request *req)
24ce0183cbSArd Biesheuvel {
25ce0183cbSArd Biesheuvel 	if (!IS_ALIGNED(req->cryptlen, dev->align_size))
26ce0183cbSArd Biesheuvel 		return -EINVAL;
27ce0183cbSArd Biesheuvel 	else
28ce0183cbSArd Biesheuvel 		return dev->enqueue(dev, &req->base);
29ce0183cbSArd Biesheuvel }
30ce0183cbSArd Biesheuvel 
31ce0183cbSArd Biesheuvel static int rk_aes_setkey(struct crypto_skcipher *cipher,
32ce0183cbSArd Biesheuvel 			 const u8 *key, unsigned int keylen)
33ce0183cbSArd Biesheuvel {
34ce0183cbSArd Biesheuvel 	struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher);
35ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
36ce0183cbSArd Biesheuvel 
37ce0183cbSArd Biesheuvel 	if (keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_192 &&
38674f368aSEric Biggers 	    keylen != AES_KEYSIZE_256)
39ce0183cbSArd Biesheuvel 		return -EINVAL;
40ce0183cbSArd Biesheuvel 	ctx->keylen = keylen;
41ce0183cbSArd Biesheuvel 	memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, key, keylen);
42ce0183cbSArd Biesheuvel 	return 0;
43ce0183cbSArd Biesheuvel }
44ce0183cbSArd Biesheuvel 
45ce0183cbSArd Biesheuvel static int rk_des_setkey(struct crypto_skcipher *cipher,
46ce0183cbSArd Biesheuvel 			 const u8 *key, unsigned int keylen)
47ce0183cbSArd Biesheuvel {
48ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher);
49ce0183cbSArd Biesheuvel 	int err;
50ce0183cbSArd Biesheuvel 
51ce0183cbSArd Biesheuvel 	err = verify_skcipher_des_key(cipher, key);
52ce0183cbSArd Biesheuvel 	if (err)
53ce0183cbSArd Biesheuvel 		return err;
54ce0183cbSArd Biesheuvel 
55ce0183cbSArd Biesheuvel 	ctx->keylen = keylen;
56ce0183cbSArd Biesheuvel 	memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen);
57ce0183cbSArd Biesheuvel 	return 0;
58ce0183cbSArd Biesheuvel }
59ce0183cbSArd Biesheuvel 
60ce0183cbSArd Biesheuvel static int rk_tdes_setkey(struct crypto_skcipher *cipher,
61ce0183cbSArd Biesheuvel 			  const u8 *key, unsigned int keylen)
62ce0183cbSArd Biesheuvel {
63ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher);
64ce0183cbSArd Biesheuvel 	int err;
65ce0183cbSArd Biesheuvel 
66ce0183cbSArd Biesheuvel 	err = verify_skcipher_des3_key(cipher, key);
67ce0183cbSArd Biesheuvel 	if (err)
68ce0183cbSArd Biesheuvel 		return err;
69ce0183cbSArd Biesheuvel 
70ce0183cbSArd Biesheuvel 	ctx->keylen = keylen;
71ce0183cbSArd Biesheuvel 	memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen);
72ce0183cbSArd Biesheuvel 	return 0;
73ce0183cbSArd Biesheuvel }
74ce0183cbSArd Biesheuvel 
75ce0183cbSArd Biesheuvel static int rk_aes_ecb_encrypt(struct skcipher_request *req)
76ce0183cbSArd Biesheuvel {
77ce0183cbSArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
78ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
79ce0183cbSArd Biesheuvel 	struct rk_crypto_info *dev = ctx->dev;
80ce0183cbSArd Biesheuvel 
81ce0183cbSArd Biesheuvel 	ctx->mode = RK_CRYPTO_AES_ECB_MODE;
82ce0183cbSArd Biesheuvel 	return rk_handle_req(dev, req);
83ce0183cbSArd Biesheuvel }
84ce0183cbSArd Biesheuvel 
85ce0183cbSArd Biesheuvel static int rk_aes_ecb_decrypt(struct skcipher_request *req)
86ce0183cbSArd Biesheuvel {
87ce0183cbSArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
88ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
89ce0183cbSArd Biesheuvel 	struct rk_crypto_info *dev = ctx->dev;
90ce0183cbSArd Biesheuvel 
91ce0183cbSArd Biesheuvel 	ctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC;
92ce0183cbSArd Biesheuvel 	return rk_handle_req(dev, req);
93ce0183cbSArd Biesheuvel }
94ce0183cbSArd Biesheuvel 
95ce0183cbSArd Biesheuvel static int rk_aes_cbc_encrypt(struct skcipher_request *req)
96ce0183cbSArd Biesheuvel {
97ce0183cbSArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
98ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
99ce0183cbSArd Biesheuvel 	struct rk_crypto_info *dev = ctx->dev;
100ce0183cbSArd Biesheuvel 
101ce0183cbSArd Biesheuvel 	ctx->mode = RK_CRYPTO_AES_CBC_MODE;
102ce0183cbSArd Biesheuvel 	return rk_handle_req(dev, req);
103ce0183cbSArd Biesheuvel }
104ce0183cbSArd Biesheuvel 
105ce0183cbSArd Biesheuvel static int rk_aes_cbc_decrypt(struct skcipher_request *req)
106ce0183cbSArd Biesheuvel {
107ce0183cbSArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
108ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
109ce0183cbSArd Biesheuvel 	struct rk_crypto_info *dev = ctx->dev;
110ce0183cbSArd Biesheuvel 
111ce0183cbSArd Biesheuvel 	ctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC;
112ce0183cbSArd Biesheuvel 	return rk_handle_req(dev, req);
113ce0183cbSArd Biesheuvel }
114ce0183cbSArd Biesheuvel 
115ce0183cbSArd Biesheuvel static int rk_des_ecb_encrypt(struct skcipher_request *req)
116ce0183cbSArd Biesheuvel {
117ce0183cbSArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
118ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
119ce0183cbSArd Biesheuvel 	struct rk_crypto_info *dev = ctx->dev;
120ce0183cbSArd Biesheuvel 
121ce0183cbSArd Biesheuvel 	ctx->mode = 0;
122ce0183cbSArd Biesheuvel 	return rk_handle_req(dev, req);
123ce0183cbSArd Biesheuvel }
124ce0183cbSArd Biesheuvel 
125ce0183cbSArd Biesheuvel static int rk_des_ecb_decrypt(struct skcipher_request *req)
126ce0183cbSArd Biesheuvel {
127ce0183cbSArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
128ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
129ce0183cbSArd Biesheuvel 	struct rk_crypto_info *dev = ctx->dev;
130ce0183cbSArd Biesheuvel 
131ce0183cbSArd Biesheuvel 	ctx->mode = RK_CRYPTO_DEC;
132ce0183cbSArd Biesheuvel 	return rk_handle_req(dev, req);
133ce0183cbSArd Biesheuvel }
134ce0183cbSArd Biesheuvel 
135ce0183cbSArd Biesheuvel static int rk_des_cbc_encrypt(struct skcipher_request *req)
136ce0183cbSArd Biesheuvel {
137ce0183cbSArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
138ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
139ce0183cbSArd Biesheuvel 	struct rk_crypto_info *dev = ctx->dev;
140ce0183cbSArd Biesheuvel 
141ce0183cbSArd Biesheuvel 	ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC;
142ce0183cbSArd Biesheuvel 	return rk_handle_req(dev, req);
143ce0183cbSArd Biesheuvel }
144ce0183cbSArd Biesheuvel 
145ce0183cbSArd Biesheuvel static int rk_des_cbc_decrypt(struct skcipher_request *req)
146ce0183cbSArd Biesheuvel {
147ce0183cbSArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
148ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
149ce0183cbSArd Biesheuvel 	struct rk_crypto_info *dev = ctx->dev;
150ce0183cbSArd Biesheuvel 
151ce0183cbSArd Biesheuvel 	ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC;
152ce0183cbSArd Biesheuvel 	return rk_handle_req(dev, req);
153ce0183cbSArd Biesheuvel }
154ce0183cbSArd Biesheuvel 
155ce0183cbSArd Biesheuvel static int rk_des3_ede_ecb_encrypt(struct skcipher_request *req)
156ce0183cbSArd Biesheuvel {
157ce0183cbSArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
158ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
159ce0183cbSArd Biesheuvel 	struct rk_crypto_info *dev = ctx->dev;
160ce0183cbSArd Biesheuvel 
161ce0183cbSArd Biesheuvel 	ctx->mode = RK_CRYPTO_TDES_SELECT;
162ce0183cbSArd Biesheuvel 	return rk_handle_req(dev, req);
163ce0183cbSArd Biesheuvel }
164ce0183cbSArd Biesheuvel 
165ce0183cbSArd Biesheuvel static int rk_des3_ede_ecb_decrypt(struct skcipher_request *req)
166ce0183cbSArd Biesheuvel {
167ce0183cbSArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
168ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
169ce0183cbSArd Biesheuvel 	struct rk_crypto_info *dev = ctx->dev;
170ce0183cbSArd Biesheuvel 
171ce0183cbSArd Biesheuvel 	ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC;
172ce0183cbSArd Biesheuvel 	return rk_handle_req(dev, req);
173ce0183cbSArd Biesheuvel }
174ce0183cbSArd Biesheuvel 
175ce0183cbSArd Biesheuvel static int rk_des3_ede_cbc_encrypt(struct skcipher_request *req)
176ce0183cbSArd Biesheuvel {
177ce0183cbSArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
178ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
179ce0183cbSArd Biesheuvel 	struct rk_crypto_info *dev = ctx->dev;
180ce0183cbSArd Biesheuvel 
181ce0183cbSArd Biesheuvel 	ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC;
182ce0183cbSArd Biesheuvel 	return rk_handle_req(dev, req);
183ce0183cbSArd Biesheuvel }
184ce0183cbSArd Biesheuvel 
185ce0183cbSArd Biesheuvel static int rk_des3_ede_cbc_decrypt(struct skcipher_request *req)
186ce0183cbSArd Biesheuvel {
187ce0183cbSArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
188ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
189ce0183cbSArd Biesheuvel 	struct rk_crypto_info *dev = ctx->dev;
190ce0183cbSArd Biesheuvel 
191ce0183cbSArd Biesheuvel 	ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC |
192ce0183cbSArd Biesheuvel 		    RK_CRYPTO_DEC;
193ce0183cbSArd Biesheuvel 	return rk_handle_req(dev, req);
194ce0183cbSArd Biesheuvel }
195ce0183cbSArd Biesheuvel 
196ce0183cbSArd Biesheuvel static void rk_ablk_hw_init(struct rk_crypto_info *dev)
197ce0183cbSArd Biesheuvel {
198ce0183cbSArd Biesheuvel 	struct skcipher_request *req =
199ce0183cbSArd Biesheuvel 		skcipher_request_cast(dev->async_req);
200ce0183cbSArd Biesheuvel 	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req);
201ce0183cbSArd Biesheuvel 	struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher);
202ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher);
203ce0183cbSArd Biesheuvel 	u32 ivsize, block, conf_reg = 0;
204ce0183cbSArd Biesheuvel 
205ce0183cbSArd Biesheuvel 	block = crypto_tfm_alg_blocksize(tfm);
206ce0183cbSArd Biesheuvel 	ivsize = crypto_skcipher_ivsize(cipher);
207ce0183cbSArd Biesheuvel 
208ce0183cbSArd Biesheuvel 	if (block == DES_BLOCK_SIZE) {
209ce0183cbSArd Biesheuvel 		ctx->mode |= RK_CRYPTO_TDES_FIFO_MODE |
210ce0183cbSArd Biesheuvel 			     RK_CRYPTO_TDES_BYTESWAP_KEY |
211ce0183cbSArd Biesheuvel 			     RK_CRYPTO_TDES_BYTESWAP_IV;
212ce0183cbSArd Biesheuvel 		CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, ctx->mode);
213ce0183cbSArd Biesheuvel 		memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize);
214ce0183cbSArd Biesheuvel 		conf_reg = RK_CRYPTO_DESSEL;
215ce0183cbSArd Biesheuvel 	} else {
216ce0183cbSArd Biesheuvel 		ctx->mode |= RK_CRYPTO_AES_FIFO_MODE |
217ce0183cbSArd Biesheuvel 			     RK_CRYPTO_AES_KEY_CHANGE |
218ce0183cbSArd Biesheuvel 			     RK_CRYPTO_AES_BYTESWAP_KEY |
219ce0183cbSArd Biesheuvel 			     RK_CRYPTO_AES_BYTESWAP_IV;
220ce0183cbSArd Biesheuvel 		if (ctx->keylen == AES_KEYSIZE_192)
221ce0183cbSArd Biesheuvel 			ctx->mode |= RK_CRYPTO_AES_192BIT_key;
222ce0183cbSArd Biesheuvel 		else if (ctx->keylen == AES_KEYSIZE_256)
223ce0183cbSArd Biesheuvel 			ctx->mode |= RK_CRYPTO_AES_256BIT_key;
224ce0183cbSArd Biesheuvel 		CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, ctx->mode);
225ce0183cbSArd Biesheuvel 		memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, req->iv, ivsize);
226ce0183cbSArd Biesheuvel 	}
227ce0183cbSArd Biesheuvel 	conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO |
228ce0183cbSArd Biesheuvel 		    RK_CRYPTO_BYTESWAP_BRFIFO;
229ce0183cbSArd Biesheuvel 	CRYPTO_WRITE(dev, RK_CRYPTO_CONF, conf_reg);
230ce0183cbSArd Biesheuvel 	CRYPTO_WRITE(dev, RK_CRYPTO_INTENA,
231ce0183cbSArd Biesheuvel 		     RK_CRYPTO_BCDMA_ERR_ENA | RK_CRYPTO_BCDMA_DONE_ENA);
232ce0183cbSArd Biesheuvel }
233ce0183cbSArd Biesheuvel 
234ce0183cbSArd Biesheuvel static void crypto_dma_start(struct rk_crypto_info *dev)
235ce0183cbSArd Biesheuvel {
236ce0183cbSArd Biesheuvel 	CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAS, dev->addr_in);
237ce0183cbSArd Biesheuvel 	CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAL, dev->count / 4);
238ce0183cbSArd Biesheuvel 	CRYPTO_WRITE(dev, RK_CRYPTO_BTDMAS, dev->addr_out);
239ce0183cbSArd Biesheuvel 	CRYPTO_WRITE(dev, RK_CRYPTO_CTRL, RK_CRYPTO_BLOCK_START |
240ce0183cbSArd Biesheuvel 		     _SBF(RK_CRYPTO_BLOCK_START, 16));
241ce0183cbSArd Biesheuvel }
242ce0183cbSArd Biesheuvel 
243ce0183cbSArd Biesheuvel static int rk_set_data_start(struct rk_crypto_info *dev)
244ce0183cbSArd Biesheuvel {
245ce0183cbSArd Biesheuvel 	int err;
246ce0183cbSArd Biesheuvel 	struct skcipher_request *req =
247ce0183cbSArd Biesheuvel 		skcipher_request_cast(dev->async_req);
248ce0183cbSArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
249ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
250ce0183cbSArd Biesheuvel 	u32 ivsize = crypto_skcipher_ivsize(tfm);
251ce0183cbSArd Biesheuvel 	u8 *src_last_blk = page_address(sg_page(dev->sg_src)) +
252ce0183cbSArd Biesheuvel 		dev->sg_src->offset + dev->sg_src->length - ivsize;
253ce0183cbSArd Biesheuvel 
254ce0183cbSArd Biesheuvel 	/* Store the iv that need to be updated in chain mode.
255ce0183cbSArd Biesheuvel 	 * And update the IV buffer to contain the next IV for decryption mode.
256ce0183cbSArd Biesheuvel 	 */
257ce0183cbSArd Biesheuvel 	if (ctx->mode & RK_CRYPTO_DEC) {
258ce0183cbSArd Biesheuvel 		memcpy(ctx->iv, src_last_blk, ivsize);
259ce0183cbSArd Biesheuvel 		sg_pcopy_to_buffer(dev->first, dev->src_nents, req->iv,
260ce0183cbSArd Biesheuvel 				   ivsize, dev->total - ivsize);
261ce0183cbSArd Biesheuvel 	}
262ce0183cbSArd Biesheuvel 
263ce0183cbSArd Biesheuvel 	err = dev->load_data(dev, dev->sg_src, dev->sg_dst);
264ce0183cbSArd Biesheuvel 	if (!err)
265ce0183cbSArd Biesheuvel 		crypto_dma_start(dev);
266ce0183cbSArd Biesheuvel 	return err;
267ce0183cbSArd Biesheuvel }
268ce0183cbSArd Biesheuvel 
269ce0183cbSArd Biesheuvel static int rk_ablk_start(struct rk_crypto_info *dev)
270ce0183cbSArd Biesheuvel {
271ce0183cbSArd Biesheuvel 	struct skcipher_request *req =
272ce0183cbSArd Biesheuvel 		skcipher_request_cast(dev->async_req);
273ce0183cbSArd Biesheuvel 	unsigned long flags;
274ce0183cbSArd Biesheuvel 	int err = 0;
275ce0183cbSArd Biesheuvel 
276ce0183cbSArd Biesheuvel 	dev->left_bytes = req->cryptlen;
277ce0183cbSArd Biesheuvel 	dev->total = req->cryptlen;
278ce0183cbSArd Biesheuvel 	dev->sg_src = req->src;
279ce0183cbSArd Biesheuvel 	dev->first = req->src;
280ce0183cbSArd Biesheuvel 	dev->src_nents = sg_nents(req->src);
281ce0183cbSArd Biesheuvel 	dev->sg_dst = req->dst;
282ce0183cbSArd Biesheuvel 	dev->dst_nents = sg_nents(req->dst);
283ce0183cbSArd Biesheuvel 	dev->aligned = 1;
284ce0183cbSArd Biesheuvel 
285ce0183cbSArd Biesheuvel 	spin_lock_irqsave(&dev->lock, flags);
286ce0183cbSArd Biesheuvel 	rk_ablk_hw_init(dev);
287ce0183cbSArd Biesheuvel 	err = rk_set_data_start(dev);
288ce0183cbSArd Biesheuvel 	spin_unlock_irqrestore(&dev->lock, flags);
289ce0183cbSArd Biesheuvel 	return err;
290ce0183cbSArd Biesheuvel }
291ce0183cbSArd Biesheuvel 
292ce0183cbSArd Biesheuvel static void rk_iv_copyback(struct rk_crypto_info *dev)
293ce0183cbSArd Biesheuvel {
294ce0183cbSArd Biesheuvel 	struct skcipher_request *req =
295ce0183cbSArd Biesheuvel 		skcipher_request_cast(dev->async_req);
296ce0183cbSArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
297ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
298ce0183cbSArd Biesheuvel 	u32 ivsize = crypto_skcipher_ivsize(tfm);
299ce0183cbSArd Biesheuvel 
300ce0183cbSArd Biesheuvel 	/* Update the IV buffer to contain the next IV for encryption mode. */
301ce0183cbSArd Biesheuvel 	if (!(ctx->mode & RK_CRYPTO_DEC)) {
302ce0183cbSArd Biesheuvel 		if (dev->aligned) {
303ce0183cbSArd Biesheuvel 			memcpy(req->iv, sg_virt(dev->sg_dst) +
304ce0183cbSArd Biesheuvel 				dev->sg_dst->length - ivsize, ivsize);
305ce0183cbSArd Biesheuvel 		} else {
306ce0183cbSArd Biesheuvel 			memcpy(req->iv, dev->addr_vir +
307ce0183cbSArd Biesheuvel 				dev->count - ivsize, ivsize);
308ce0183cbSArd Biesheuvel 		}
309ce0183cbSArd Biesheuvel 	}
310ce0183cbSArd Biesheuvel }
311ce0183cbSArd Biesheuvel 
312ce0183cbSArd Biesheuvel static void rk_update_iv(struct rk_crypto_info *dev)
313ce0183cbSArd Biesheuvel {
314ce0183cbSArd Biesheuvel 	struct skcipher_request *req =
315ce0183cbSArd Biesheuvel 		skcipher_request_cast(dev->async_req);
316ce0183cbSArd Biesheuvel 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
317ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
318ce0183cbSArd Biesheuvel 	u32 ivsize = crypto_skcipher_ivsize(tfm);
319ce0183cbSArd Biesheuvel 	u8 *new_iv = NULL;
320ce0183cbSArd Biesheuvel 
321ce0183cbSArd Biesheuvel 	if (ctx->mode & RK_CRYPTO_DEC) {
322ce0183cbSArd Biesheuvel 		new_iv = ctx->iv;
323ce0183cbSArd Biesheuvel 	} else {
324ce0183cbSArd Biesheuvel 		new_iv = page_address(sg_page(dev->sg_dst)) +
325ce0183cbSArd Biesheuvel 			 dev->sg_dst->offset + dev->sg_dst->length - ivsize;
326ce0183cbSArd Biesheuvel 	}
327ce0183cbSArd Biesheuvel 
328ce0183cbSArd Biesheuvel 	if (ivsize == DES_BLOCK_SIZE)
329ce0183cbSArd Biesheuvel 		memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, new_iv, ivsize);
330ce0183cbSArd Biesheuvel 	else if (ivsize == AES_BLOCK_SIZE)
331ce0183cbSArd Biesheuvel 		memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, new_iv, ivsize);
332ce0183cbSArd Biesheuvel }
333ce0183cbSArd Biesheuvel 
334ce0183cbSArd Biesheuvel /* return:
335ce0183cbSArd Biesheuvel  *	true	some err was occurred
336ce0183cbSArd Biesheuvel  *	fault	no err, continue
337ce0183cbSArd Biesheuvel  */
338ce0183cbSArd Biesheuvel static int rk_ablk_rx(struct rk_crypto_info *dev)
339ce0183cbSArd Biesheuvel {
340ce0183cbSArd Biesheuvel 	int err = 0;
341ce0183cbSArd Biesheuvel 	struct skcipher_request *req =
342ce0183cbSArd Biesheuvel 		skcipher_request_cast(dev->async_req);
343ce0183cbSArd Biesheuvel 
344ce0183cbSArd Biesheuvel 	dev->unload_data(dev);
345ce0183cbSArd Biesheuvel 	if (!dev->aligned) {
346ce0183cbSArd Biesheuvel 		if (!sg_pcopy_from_buffer(req->dst, dev->dst_nents,
347ce0183cbSArd Biesheuvel 					  dev->addr_vir, dev->count,
348ce0183cbSArd Biesheuvel 					  dev->total - dev->left_bytes -
349ce0183cbSArd Biesheuvel 					  dev->count)) {
350ce0183cbSArd Biesheuvel 			err = -EINVAL;
351ce0183cbSArd Biesheuvel 			goto out_rx;
352ce0183cbSArd Biesheuvel 		}
353ce0183cbSArd Biesheuvel 	}
354ce0183cbSArd Biesheuvel 	if (dev->left_bytes) {
355ce0183cbSArd Biesheuvel 		rk_update_iv(dev);
356ce0183cbSArd Biesheuvel 		if (dev->aligned) {
357ce0183cbSArd Biesheuvel 			if (sg_is_last(dev->sg_src)) {
358ce0183cbSArd Biesheuvel 				dev_err(dev->dev, "[%s:%d] Lack of data\n",
359ce0183cbSArd Biesheuvel 					__func__, __LINE__);
360ce0183cbSArd Biesheuvel 				err = -ENOMEM;
361ce0183cbSArd Biesheuvel 				goto out_rx;
362ce0183cbSArd Biesheuvel 			}
363ce0183cbSArd Biesheuvel 			dev->sg_src = sg_next(dev->sg_src);
364ce0183cbSArd Biesheuvel 			dev->sg_dst = sg_next(dev->sg_dst);
365ce0183cbSArd Biesheuvel 		}
366ce0183cbSArd Biesheuvel 		err = rk_set_data_start(dev);
367ce0183cbSArd Biesheuvel 	} else {
368ce0183cbSArd Biesheuvel 		rk_iv_copyback(dev);
369ce0183cbSArd Biesheuvel 		/* here show the calculation is over without any err */
370ce0183cbSArd Biesheuvel 		dev->complete(dev->async_req, 0);
371ce0183cbSArd Biesheuvel 		tasklet_schedule(&dev->queue_task);
372ce0183cbSArd Biesheuvel 	}
373ce0183cbSArd Biesheuvel out_rx:
374ce0183cbSArd Biesheuvel 	return err;
375ce0183cbSArd Biesheuvel }
376ce0183cbSArd Biesheuvel 
377ce0183cbSArd Biesheuvel static int rk_ablk_init_tfm(struct crypto_skcipher *tfm)
378ce0183cbSArd Biesheuvel {
379ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
380ce0183cbSArd Biesheuvel 	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
381ce0183cbSArd Biesheuvel 	struct rk_crypto_tmp *algt;
382ce0183cbSArd Biesheuvel 
383ce0183cbSArd Biesheuvel 	algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);
384ce0183cbSArd Biesheuvel 
385ce0183cbSArd Biesheuvel 	ctx->dev = algt->dev;
386ce0183cbSArd Biesheuvel 	ctx->dev->align_size = crypto_tfm_alg_alignmask(crypto_skcipher_tfm(tfm)) + 1;
387ce0183cbSArd Biesheuvel 	ctx->dev->start = rk_ablk_start;
388ce0183cbSArd Biesheuvel 	ctx->dev->update = rk_ablk_rx;
389ce0183cbSArd Biesheuvel 	ctx->dev->complete = rk_crypto_complete;
390ce0183cbSArd Biesheuvel 	ctx->dev->addr_vir = (char *)__get_free_page(GFP_KERNEL);
391ce0183cbSArd Biesheuvel 
392ce0183cbSArd Biesheuvel 	return ctx->dev->addr_vir ? ctx->dev->enable_clk(ctx->dev) : -ENOMEM;
393ce0183cbSArd Biesheuvel }
394ce0183cbSArd Biesheuvel 
395ce0183cbSArd Biesheuvel static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm)
396ce0183cbSArd Biesheuvel {
397ce0183cbSArd Biesheuvel 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
398ce0183cbSArd Biesheuvel 
399ce0183cbSArd Biesheuvel 	free_page((unsigned long)ctx->dev->addr_vir);
400ce0183cbSArd Biesheuvel 	ctx->dev->disable_clk(ctx->dev);
401ce0183cbSArd Biesheuvel }
402ce0183cbSArd Biesheuvel 
403ce0183cbSArd Biesheuvel struct rk_crypto_tmp rk_ecb_aes_alg = {
404ce0183cbSArd Biesheuvel 	.type = ALG_TYPE_CIPHER,
405ce0183cbSArd Biesheuvel 	.alg.skcipher = {
406ce0183cbSArd Biesheuvel 		.base.cra_name		= "ecb(aes)",
407ce0183cbSArd Biesheuvel 		.base.cra_driver_name	= "ecb-aes-rk",
408ce0183cbSArd Biesheuvel 		.base.cra_priority	= 300,
409ce0183cbSArd Biesheuvel 		.base.cra_flags		= CRYPTO_ALG_ASYNC,
410ce0183cbSArd Biesheuvel 		.base.cra_blocksize	= AES_BLOCK_SIZE,
411ce0183cbSArd Biesheuvel 		.base.cra_ctxsize	= sizeof(struct rk_cipher_ctx),
412ce0183cbSArd Biesheuvel 		.base.cra_alignmask	= 0x0f,
413ce0183cbSArd Biesheuvel 		.base.cra_module	= THIS_MODULE,
414ce0183cbSArd Biesheuvel 
415ce0183cbSArd Biesheuvel 		.init			= rk_ablk_init_tfm,
416ce0183cbSArd Biesheuvel 		.exit			= rk_ablk_exit_tfm,
417ce0183cbSArd Biesheuvel 		.min_keysize		= AES_MIN_KEY_SIZE,
418ce0183cbSArd Biesheuvel 		.max_keysize		= AES_MAX_KEY_SIZE,
419ce0183cbSArd Biesheuvel 		.setkey			= rk_aes_setkey,
420ce0183cbSArd Biesheuvel 		.encrypt		= rk_aes_ecb_encrypt,
421ce0183cbSArd Biesheuvel 		.decrypt		= rk_aes_ecb_decrypt,
422ce0183cbSArd Biesheuvel 	}
423ce0183cbSArd Biesheuvel };
424ce0183cbSArd Biesheuvel 
425ce0183cbSArd Biesheuvel struct rk_crypto_tmp rk_cbc_aes_alg = {
426ce0183cbSArd Biesheuvel 	.type = ALG_TYPE_CIPHER,
427ce0183cbSArd Biesheuvel 	.alg.skcipher = {
428ce0183cbSArd Biesheuvel 		.base.cra_name		= "cbc(aes)",
429ce0183cbSArd Biesheuvel 		.base.cra_driver_name	= "cbc-aes-rk",
430ce0183cbSArd Biesheuvel 		.base.cra_priority	= 300,
431ce0183cbSArd Biesheuvel 		.base.cra_flags		= CRYPTO_ALG_ASYNC,
432ce0183cbSArd Biesheuvel 		.base.cra_blocksize	= AES_BLOCK_SIZE,
433ce0183cbSArd Biesheuvel 		.base.cra_ctxsize	= sizeof(struct rk_cipher_ctx),
434ce0183cbSArd Biesheuvel 		.base.cra_alignmask	= 0x0f,
435ce0183cbSArd Biesheuvel 		.base.cra_module	= THIS_MODULE,
436ce0183cbSArd Biesheuvel 
437ce0183cbSArd Biesheuvel 		.init			= rk_ablk_init_tfm,
438ce0183cbSArd Biesheuvel 		.exit			= rk_ablk_exit_tfm,
439ce0183cbSArd Biesheuvel 		.min_keysize		= AES_MIN_KEY_SIZE,
440ce0183cbSArd Biesheuvel 		.max_keysize		= AES_MAX_KEY_SIZE,
441ce0183cbSArd Biesheuvel 		.ivsize			= AES_BLOCK_SIZE,
442ce0183cbSArd Biesheuvel 		.setkey			= rk_aes_setkey,
443ce0183cbSArd Biesheuvel 		.encrypt		= rk_aes_cbc_encrypt,
444ce0183cbSArd Biesheuvel 		.decrypt		= rk_aes_cbc_decrypt,
445ce0183cbSArd Biesheuvel 	}
446ce0183cbSArd Biesheuvel };
447ce0183cbSArd Biesheuvel 
448ce0183cbSArd Biesheuvel struct rk_crypto_tmp rk_ecb_des_alg = {
449ce0183cbSArd Biesheuvel 	.type = ALG_TYPE_CIPHER,
450ce0183cbSArd Biesheuvel 	.alg.skcipher = {
451ce0183cbSArd Biesheuvel 		.base.cra_name		= "ecb(des)",
452ce0183cbSArd Biesheuvel 		.base.cra_driver_name	= "ecb-des-rk",
453ce0183cbSArd Biesheuvel 		.base.cra_priority	= 300,
454ce0183cbSArd Biesheuvel 		.base.cra_flags		= CRYPTO_ALG_ASYNC,
455ce0183cbSArd Biesheuvel 		.base.cra_blocksize	= DES_BLOCK_SIZE,
456ce0183cbSArd Biesheuvel 		.base.cra_ctxsize	= sizeof(struct rk_cipher_ctx),
457ce0183cbSArd Biesheuvel 		.base.cra_alignmask	= 0x07,
458ce0183cbSArd Biesheuvel 		.base.cra_module	= THIS_MODULE,
459ce0183cbSArd Biesheuvel 
460ce0183cbSArd Biesheuvel 		.init			= rk_ablk_init_tfm,
461ce0183cbSArd Biesheuvel 		.exit			= rk_ablk_exit_tfm,
462ce0183cbSArd Biesheuvel 		.min_keysize		= DES_KEY_SIZE,
463ce0183cbSArd Biesheuvel 		.max_keysize		= DES_KEY_SIZE,
464ce0183cbSArd Biesheuvel 		.setkey			= rk_des_setkey,
465ce0183cbSArd Biesheuvel 		.encrypt		= rk_des_ecb_encrypt,
466ce0183cbSArd Biesheuvel 		.decrypt		= rk_des_ecb_decrypt,
467ce0183cbSArd Biesheuvel 	}
468ce0183cbSArd Biesheuvel };
469ce0183cbSArd Biesheuvel 
470ce0183cbSArd Biesheuvel struct rk_crypto_tmp rk_cbc_des_alg = {
471ce0183cbSArd Biesheuvel 	.type = ALG_TYPE_CIPHER,
472ce0183cbSArd Biesheuvel 	.alg.skcipher = {
473ce0183cbSArd Biesheuvel 		.base.cra_name		= "cbc(des)",
474ce0183cbSArd Biesheuvel 		.base.cra_driver_name	= "cbc-des-rk",
475ce0183cbSArd Biesheuvel 		.base.cra_priority	= 300,
476ce0183cbSArd Biesheuvel 		.base.cra_flags		= CRYPTO_ALG_ASYNC,
477ce0183cbSArd Biesheuvel 		.base.cra_blocksize	= DES_BLOCK_SIZE,
478ce0183cbSArd Biesheuvel 		.base.cra_ctxsize	= sizeof(struct rk_cipher_ctx),
479ce0183cbSArd Biesheuvel 		.base.cra_alignmask	= 0x07,
480ce0183cbSArd Biesheuvel 		.base.cra_module	= THIS_MODULE,
481ce0183cbSArd Biesheuvel 
482ce0183cbSArd Biesheuvel 		.init			= rk_ablk_init_tfm,
483ce0183cbSArd Biesheuvel 		.exit			= rk_ablk_exit_tfm,
484ce0183cbSArd Biesheuvel 		.min_keysize		= DES_KEY_SIZE,
485ce0183cbSArd Biesheuvel 		.max_keysize		= DES_KEY_SIZE,
486ce0183cbSArd Biesheuvel 		.ivsize			= DES_BLOCK_SIZE,
487ce0183cbSArd Biesheuvel 		.setkey			= rk_des_setkey,
488ce0183cbSArd Biesheuvel 		.encrypt		= rk_des_cbc_encrypt,
489ce0183cbSArd Biesheuvel 		.decrypt		= rk_des_cbc_decrypt,
490ce0183cbSArd Biesheuvel 	}
491ce0183cbSArd Biesheuvel };
492ce0183cbSArd Biesheuvel 
493ce0183cbSArd Biesheuvel struct rk_crypto_tmp rk_ecb_des3_ede_alg = {
494ce0183cbSArd Biesheuvel 	.type = ALG_TYPE_CIPHER,
495ce0183cbSArd Biesheuvel 	.alg.skcipher = {
496ce0183cbSArd Biesheuvel 		.base.cra_name		= "ecb(des3_ede)",
497ce0183cbSArd Biesheuvel 		.base.cra_driver_name	= "ecb-des3-ede-rk",
498ce0183cbSArd Biesheuvel 		.base.cra_priority	= 300,
499ce0183cbSArd Biesheuvel 		.base.cra_flags		= CRYPTO_ALG_ASYNC,
500ce0183cbSArd Biesheuvel 		.base.cra_blocksize	= DES_BLOCK_SIZE,
501ce0183cbSArd Biesheuvel 		.base.cra_ctxsize	= sizeof(struct rk_cipher_ctx),
502ce0183cbSArd Biesheuvel 		.base.cra_alignmask	= 0x07,
503ce0183cbSArd Biesheuvel 		.base.cra_module	= THIS_MODULE,
504ce0183cbSArd Biesheuvel 
505ce0183cbSArd Biesheuvel 		.init			= rk_ablk_init_tfm,
506ce0183cbSArd Biesheuvel 		.exit			= rk_ablk_exit_tfm,
507ce0183cbSArd Biesheuvel 		.min_keysize		= DES3_EDE_KEY_SIZE,
508ce0183cbSArd Biesheuvel 		.max_keysize		= DES3_EDE_KEY_SIZE,
509ce0183cbSArd Biesheuvel 		.ivsize			= DES_BLOCK_SIZE,
510ce0183cbSArd Biesheuvel 		.setkey			= rk_tdes_setkey,
511ce0183cbSArd Biesheuvel 		.encrypt		= rk_des3_ede_ecb_encrypt,
512ce0183cbSArd Biesheuvel 		.decrypt		= rk_des3_ede_ecb_decrypt,
513ce0183cbSArd Biesheuvel 	}
514ce0183cbSArd Biesheuvel };
515ce0183cbSArd Biesheuvel 
516ce0183cbSArd Biesheuvel struct rk_crypto_tmp rk_cbc_des3_ede_alg = {
517ce0183cbSArd Biesheuvel 	.type = ALG_TYPE_CIPHER,
518ce0183cbSArd Biesheuvel 	.alg.skcipher = {
519ce0183cbSArd Biesheuvel 		.base.cra_name		= "cbc(des3_ede)",
520ce0183cbSArd Biesheuvel 		.base.cra_driver_name	= "cbc-des3-ede-rk",
521ce0183cbSArd Biesheuvel 		.base.cra_priority	= 300,
522ce0183cbSArd Biesheuvel 		.base.cra_flags		= CRYPTO_ALG_ASYNC,
523ce0183cbSArd Biesheuvel 		.base.cra_blocksize	= DES_BLOCK_SIZE,
524ce0183cbSArd Biesheuvel 		.base.cra_ctxsize	= sizeof(struct rk_cipher_ctx),
525ce0183cbSArd Biesheuvel 		.base.cra_alignmask	= 0x07,
526ce0183cbSArd Biesheuvel 		.base.cra_module	= THIS_MODULE,
527ce0183cbSArd Biesheuvel 
528ce0183cbSArd Biesheuvel 		.init			= rk_ablk_init_tfm,
529ce0183cbSArd Biesheuvel 		.exit			= rk_ablk_exit_tfm,
530ce0183cbSArd Biesheuvel 		.min_keysize		= DES3_EDE_KEY_SIZE,
531ce0183cbSArd Biesheuvel 		.max_keysize		= DES3_EDE_KEY_SIZE,
532ce0183cbSArd Biesheuvel 		.ivsize			= DES_BLOCK_SIZE,
533ce0183cbSArd Biesheuvel 		.setkey			= rk_tdes_setkey,
534ce0183cbSArd Biesheuvel 		.encrypt		= rk_des3_ede_cbc_encrypt,
535ce0183cbSArd Biesheuvel 		.decrypt		= rk_des3_ede_cbc_decrypt,
536ce0183cbSArd Biesheuvel 	}
537ce0183cbSArd Biesheuvel };
538