xref: /linux/drivers/crypto/stm32/stm32-cryp.c (revision 9e054ec21ef8344345b28603fb272fe999f735db)
1*9e054ec2SFabien DESSENNE /*
2*9e054ec2SFabien DESSENNE  * Copyright (C) STMicroelectronics SA 2017
3*9e054ec2SFabien DESSENNE  * Author: Fabien Dessenne <fabien.dessenne@st.com>
4*9e054ec2SFabien DESSENNE  * License terms:  GNU General Public License (GPL), version 2
5*9e054ec2SFabien DESSENNE  */
6*9e054ec2SFabien DESSENNE 
7*9e054ec2SFabien DESSENNE #include <linux/clk.h>
8*9e054ec2SFabien DESSENNE #include <linux/delay.h>
9*9e054ec2SFabien DESSENNE #include <linux/interrupt.h>
10*9e054ec2SFabien DESSENNE #include <linux/iopoll.h>
11*9e054ec2SFabien DESSENNE #include <linux/module.h>
12*9e054ec2SFabien DESSENNE #include <linux/of_device.h>
13*9e054ec2SFabien DESSENNE #include <linux/platform_device.h>
14*9e054ec2SFabien DESSENNE #include <linux/reset.h>
15*9e054ec2SFabien DESSENNE 
16*9e054ec2SFabien DESSENNE #include <crypto/aes.h>
17*9e054ec2SFabien DESSENNE #include <crypto/des.h>
18*9e054ec2SFabien DESSENNE #include <crypto/engine.h>
19*9e054ec2SFabien DESSENNE #include <crypto/scatterwalk.h>
20*9e054ec2SFabien DESSENNE 
21*9e054ec2SFabien DESSENNE #define DRIVER_NAME             "stm32-cryp"
22*9e054ec2SFabien DESSENNE 
23*9e054ec2SFabien DESSENNE /* Bit [0] encrypt / decrypt */
24*9e054ec2SFabien DESSENNE #define FLG_ENCRYPT             BIT(0)
25*9e054ec2SFabien DESSENNE /* Bit [8..1] algo & operation mode */
26*9e054ec2SFabien DESSENNE #define FLG_AES                 BIT(1)
27*9e054ec2SFabien DESSENNE #define FLG_DES                 BIT(2)
28*9e054ec2SFabien DESSENNE #define FLG_TDES                BIT(3)
29*9e054ec2SFabien DESSENNE #define FLG_ECB                 BIT(4)
30*9e054ec2SFabien DESSENNE #define FLG_CBC                 BIT(5)
31*9e054ec2SFabien DESSENNE #define FLG_CTR                 BIT(6)
32*9e054ec2SFabien DESSENNE /* Mode mask = bits [15..0] */
33*9e054ec2SFabien DESSENNE #define FLG_MODE_MASK           GENMASK(15, 0)
34*9e054ec2SFabien DESSENNE 
35*9e054ec2SFabien DESSENNE /* Registers */
36*9e054ec2SFabien DESSENNE #define CRYP_CR                 0x00000000
37*9e054ec2SFabien DESSENNE #define CRYP_SR                 0x00000004
38*9e054ec2SFabien DESSENNE #define CRYP_DIN                0x00000008
39*9e054ec2SFabien DESSENNE #define CRYP_DOUT               0x0000000C
40*9e054ec2SFabien DESSENNE #define CRYP_DMACR              0x00000010
41*9e054ec2SFabien DESSENNE #define CRYP_IMSCR              0x00000014
42*9e054ec2SFabien DESSENNE #define CRYP_RISR               0x00000018
43*9e054ec2SFabien DESSENNE #define CRYP_MISR               0x0000001C
44*9e054ec2SFabien DESSENNE #define CRYP_K0LR               0x00000020
45*9e054ec2SFabien DESSENNE #define CRYP_K0RR               0x00000024
46*9e054ec2SFabien DESSENNE #define CRYP_K1LR               0x00000028
47*9e054ec2SFabien DESSENNE #define CRYP_K1RR               0x0000002C
48*9e054ec2SFabien DESSENNE #define CRYP_K2LR               0x00000030
49*9e054ec2SFabien DESSENNE #define CRYP_K2RR               0x00000034
50*9e054ec2SFabien DESSENNE #define CRYP_K3LR               0x00000038
51*9e054ec2SFabien DESSENNE #define CRYP_K3RR               0x0000003C
52*9e054ec2SFabien DESSENNE #define CRYP_IV0LR              0x00000040
53*9e054ec2SFabien DESSENNE #define CRYP_IV0RR              0x00000044
54*9e054ec2SFabien DESSENNE #define CRYP_IV1LR              0x00000048
55*9e054ec2SFabien DESSENNE #define CRYP_IV1RR              0x0000004C
56*9e054ec2SFabien DESSENNE 
57*9e054ec2SFabien DESSENNE /* Registers values */
58*9e054ec2SFabien DESSENNE #define CR_DEC_NOT_ENC          0x00000004
59*9e054ec2SFabien DESSENNE #define CR_TDES_ECB             0x00000000
60*9e054ec2SFabien DESSENNE #define CR_TDES_CBC             0x00000008
61*9e054ec2SFabien DESSENNE #define CR_DES_ECB              0x00000010
62*9e054ec2SFabien DESSENNE #define CR_DES_CBC              0x00000018
63*9e054ec2SFabien DESSENNE #define CR_AES_ECB              0x00000020
64*9e054ec2SFabien DESSENNE #define CR_AES_CBC              0x00000028
65*9e054ec2SFabien DESSENNE #define CR_AES_CTR              0x00000030
66*9e054ec2SFabien DESSENNE #define CR_AES_KP               0x00000038
67*9e054ec2SFabien DESSENNE #define CR_AES_UNKNOWN          0xFFFFFFFF
68*9e054ec2SFabien DESSENNE #define CR_ALGO_MASK            0x00080038
69*9e054ec2SFabien DESSENNE #define CR_DATA32               0x00000000
70*9e054ec2SFabien DESSENNE #define CR_DATA16               0x00000040
71*9e054ec2SFabien DESSENNE #define CR_DATA8                0x00000080
72*9e054ec2SFabien DESSENNE #define CR_DATA1                0x000000C0
73*9e054ec2SFabien DESSENNE #define CR_KEY128               0x00000000
74*9e054ec2SFabien DESSENNE #define CR_KEY192               0x00000100
75*9e054ec2SFabien DESSENNE #define CR_KEY256               0x00000200
76*9e054ec2SFabien DESSENNE #define CR_FFLUSH               0x00004000
77*9e054ec2SFabien DESSENNE #define CR_CRYPEN               0x00008000
78*9e054ec2SFabien DESSENNE 
79*9e054ec2SFabien DESSENNE #define SR_BUSY                 0x00000010
80*9e054ec2SFabien DESSENNE #define SR_OFNE                 0x00000004
81*9e054ec2SFabien DESSENNE 
82*9e054ec2SFabien DESSENNE #define IMSCR_IN                BIT(0)
83*9e054ec2SFabien DESSENNE #define IMSCR_OUT               BIT(1)
84*9e054ec2SFabien DESSENNE 
85*9e054ec2SFabien DESSENNE #define MISR_IN                 BIT(0)
86*9e054ec2SFabien DESSENNE #define MISR_OUT                BIT(1)
87*9e054ec2SFabien DESSENNE 
88*9e054ec2SFabien DESSENNE /* Misc */
89*9e054ec2SFabien DESSENNE #define AES_BLOCK_32            (AES_BLOCK_SIZE / sizeof(u32))
90*9e054ec2SFabien DESSENNE #define _walked_in              (cryp->in_walk.offset - cryp->in_sg->offset)
91*9e054ec2SFabien DESSENNE #define _walked_out             (cryp->out_walk.offset - cryp->out_sg->offset)
92*9e054ec2SFabien DESSENNE 
93*9e054ec2SFabien DESSENNE struct stm32_cryp_ctx {
94*9e054ec2SFabien DESSENNE 	struct stm32_cryp       *cryp;
95*9e054ec2SFabien DESSENNE 	int                     keylen;
96*9e054ec2SFabien DESSENNE 	u32                     key[AES_KEYSIZE_256 / sizeof(u32)];
97*9e054ec2SFabien DESSENNE 	unsigned long           flags;
98*9e054ec2SFabien DESSENNE };
99*9e054ec2SFabien DESSENNE 
100*9e054ec2SFabien DESSENNE struct stm32_cryp_reqctx {
101*9e054ec2SFabien DESSENNE 	unsigned long mode;
102*9e054ec2SFabien DESSENNE };
103*9e054ec2SFabien DESSENNE 
104*9e054ec2SFabien DESSENNE struct stm32_cryp {
105*9e054ec2SFabien DESSENNE 	struct list_head        list;
106*9e054ec2SFabien DESSENNE 	struct device           *dev;
107*9e054ec2SFabien DESSENNE 	void __iomem            *regs;
108*9e054ec2SFabien DESSENNE 	struct clk              *clk;
109*9e054ec2SFabien DESSENNE 	unsigned long           flags;
110*9e054ec2SFabien DESSENNE 	u32                     irq_status;
111*9e054ec2SFabien DESSENNE 	struct stm32_cryp_ctx   *ctx;
112*9e054ec2SFabien DESSENNE 
113*9e054ec2SFabien DESSENNE 	struct crypto_engine    *engine;
114*9e054ec2SFabien DESSENNE 
115*9e054ec2SFabien DESSENNE 	struct mutex            lock; /* protects req */
116*9e054ec2SFabien DESSENNE 	struct ablkcipher_request *req;
117*9e054ec2SFabien DESSENNE 
118*9e054ec2SFabien DESSENNE 	size_t                  hw_blocksize;
119*9e054ec2SFabien DESSENNE 
120*9e054ec2SFabien DESSENNE 	size_t                  total_in;
121*9e054ec2SFabien DESSENNE 	size_t                  total_in_save;
122*9e054ec2SFabien DESSENNE 	size_t                  total_out;
123*9e054ec2SFabien DESSENNE 	size_t                  total_out_save;
124*9e054ec2SFabien DESSENNE 
125*9e054ec2SFabien DESSENNE 	struct scatterlist      *in_sg;
126*9e054ec2SFabien DESSENNE 	struct scatterlist      *out_sg;
127*9e054ec2SFabien DESSENNE 	struct scatterlist      *out_sg_save;
128*9e054ec2SFabien DESSENNE 
129*9e054ec2SFabien DESSENNE 	struct scatterlist      in_sgl;
130*9e054ec2SFabien DESSENNE 	struct scatterlist      out_sgl;
131*9e054ec2SFabien DESSENNE 	bool                    sgs_copied;
132*9e054ec2SFabien DESSENNE 
133*9e054ec2SFabien DESSENNE 	int                     in_sg_len;
134*9e054ec2SFabien DESSENNE 	int                     out_sg_len;
135*9e054ec2SFabien DESSENNE 
136*9e054ec2SFabien DESSENNE 	struct scatter_walk     in_walk;
137*9e054ec2SFabien DESSENNE 	struct scatter_walk     out_walk;
138*9e054ec2SFabien DESSENNE 
139*9e054ec2SFabien DESSENNE 	u32                     last_ctr[4];
140*9e054ec2SFabien DESSENNE };
141*9e054ec2SFabien DESSENNE 
142*9e054ec2SFabien DESSENNE struct stm32_cryp_list {
143*9e054ec2SFabien DESSENNE 	struct list_head        dev_list;
144*9e054ec2SFabien DESSENNE 	spinlock_t              lock; /* protect dev_list */
145*9e054ec2SFabien DESSENNE };
146*9e054ec2SFabien DESSENNE 
147*9e054ec2SFabien DESSENNE static struct stm32_cryp_list cryp_list = {
148*9e054ec2SFabien DESSENNE 	.dev_list = LIST_HEAD_INIT(cryp_list.dev_list),
149*9e054ec2SFabien DESSENNE 	.lock     = __SPIN_LOCK_UNLOCKED(cryp_list.lock),
150*9e054ec2SFabien DESSENNE };
151*9e054ec2SFabien DESSENNE 
152*9e054ec2SFabien DESSENNE static inline bool is_aes(struct stm32_cryp *cryp)
153*9e054ec2SFabien DESSENNE {
154*9e054ec2SFabien DESSENNE 	return cryp->flags & FLG_AES;
155*9e054ec2SFabien DESSENNE }
156*9e054ec2SFabien DESSENNE 
157*9e054ec2SFabien DESSENNE static inline bool is_des(struct stm32_cryp *cryp)
158*9e054ec2SFabien DESSENNE {
159*9e054ec2SFabien DESSENNE 	return cryp->flags & FLG_DES;
160*9e054ec2SFabien DESSENNE }
161*9e054ec2SFabien DESSENNE 
162*9e054ec2SFabien DESSENNE static inline bool is_tdes(struct stm32_cryp *cryp)
163*9e054ec2SFabien DESSENNE {
164*9e054ec2SFabien DESSENNE 	return cryp->flags & FLG_TDES;
165*9e054ec2SFabien DESSENNE }
166*9e054ec2SFabien DESSENNE 
167*9e054ec2SFabien DESSENNE static inline bool is_ecb(struct stm32_cryp *cryp)
168*9e054ec2SFabien DESSENNE {
169*9e054ec2SFabien DESSENNE 	return cryp->flags & FLG_ECB;
170*9e054ec2SFabien DESSENNE }
171*9e054ec2SFabien DESSENNE 
172*9e054ec2SFabien DESSENNE static inline bool is_cbc(struct stm32_cryp *cryp)
173*9e054ec2SFabien DESSENNE {
174*9e054ec2SFabien DESSENNE 	return cryp->flags & FLG_CBC;
175*9e054ec2SFabien DESSENNE }
176*9e054ec2SFabien DESSENNE 
177*9e054ec2SFabien DESSENNE static inline bool is_ctr(struct stm32_cryp *cryp)
178*9e054ec2SFabien DESSENNE {
179*9e054ec2SFabien DESSENNE 	return cryp->flags & FLG_CTR;
180*9e054ec2SFabien DESSENNE }
181*9e054ec2SFabien DESSENNE 
182*9e054ec2SFabien DESSENNE static inline bool is_encrypt(struct stm32_cryp *cryp)
183*9e054ec2SFabien DESSENNE {
184*9e054ec2SFabien DESSENNE 	return cryp->flags & FLG_ENCRYPT;
185*9e054ec2SFabien DESSENNE }
186*9e054ec2SFabien DESSENNE 
187*9e054ec2SFabien DESSENNE static inline bool is_decrypt(struct stm32_cryp *cryp)
188*9e054ec2SFabien DESSENNE {
189*9e054ec2SFabien DESSENNE 	return !is_encrypt(cryp);
190*9e054ec2SFabien DESSENNE }
191*9e054ec2SFabien DESSENNE 
192*9e054ec2SFabien DESSENNE static inline u32 stm32_cryp_read(struct stm32_cryp *cryp, u32 ofst)
193*9e054ec2SFabien DESSENNE {
194*9e054ec2SFabien DESSENNE 	return readl_relaxed(cryp->regs + ofst);
195*9e054ec2SFabien DESSENNE }
196*9e054ec2SFabien DESSENNE 
197*9e054ec2SFabien DESSENNE static inline void stm32_cryp_write(struct stm32_cryp *cryp, u32 ofst, u32 val)
198*9e054ec2SFabien DESSENNE {
199*9e054ec2SFabien DESSENNE 	writel_relaxed(val, cryp->regs + ofst);
200*9e054ec2SFabien DESSENNE }
201*9e054ec2SFabien DESSENNE 
202*9e054ec2SFabien DESSENNE static inline int stm32_cryp_wait_busy(struct stm32_cryp *cryp)
203*9e054ec2SFabien DESSENNE {
204*9e054ec2SFabien DESSENNE 	u32 status;
205*9e054ec2SFabien DESSENNE 
206*9e054ec2SFabien DESSENNE 	return readl_relaxed_poll_timeout(cryp->regs + CRYP_SR, status,
207*9e054ec2SFabien DESSENNE 			!(status & SR_BUSY), 10, 100000);
208*9e054ec2SFabien DESSENNE }
209*9e054ec2SFabien DESSENNE 
210*9e054ec2SFabien DESSENNE static struct stm32_cryp *stm32_cryp_find_dev(struct stm32_cryp_ctx *ctx)
211*9e054ec2SFabien DESSENNE {
212*9e054ec2SFabien DESSENNE 	struct stm32_cryp *tmp, *cryp = NULL;
213*9e054ec2SFabien DESSENNE 
214*9e054ec2SFabien DESSENNE 	spin_lock_bh(&cryp_list.lock);
215*9e054ec2SFabien DESSENNE 	if (!ctx->cryp) {
216*9e054ec2SFabien DESSENNE 		list_for_each_entry(tmp, &cryp_list.dev_list, list) {
217*9e054ec2SFabien DESSENNE 			cryp = tmp;
218*9e054ec2SFabien DESSENNE 			break;
219*9e054ec2SFabien DESSENNE 		}
220*9e054ec2SFabien DESSENNE 		ctx->cryp = cryp;
221*9e054ec2SFabien DESSENNE 	} else {
222*9e054ec2SFabien DESSENNE 		cryp = ctx->cryp;
223*9e054ec2SFabien DESSENNE 	}
224*9e054ec2SFabien DESSENNE 
225*9e054ec2SFabien DESSENNE 	spin_unlock_bh(&cryp_list.lock);
226*9e054ec2SFabien DESSENNE 
227*9e054ec2SFabien DESSENNE 	return cryp;
228*9e054ec2SFabien DESSENNE }
229*9e054ec2SFabien DESSENNE 
230*9e054ec2SFabien DESSENNE static int stm32_cryp_check_aligned(struct scatterlist *sg, size_t total,
231*9e054ec2SFabien DESSENNE 				    size_t align)
232*9e054ec2SFabien DESSENNE {
233*9e054ec2SFabien DESSENNE 	int len = 0;
234*9e054ec2SFabien DESSENNE 
235*9e054ec2SFabien DESSENNE 	if (!total)
236*9e054ec2SFabien DESSENNE 		return 0;
237*9e054ec2SFabien DESSENNE 
238*9e054ec2SFabien DESSENNE 	if (!IS_ALIGNED(total, align))
239*9e054ec2SFabien DESSENNE 		return -EINVAL;
240*9e054ec2SFabien DESSENNE 
241*9e054ec2SFabien DESSENNE 	while (sg) {
242*9e054ec2SFabien DESSENNE 		if (!IS_ALIGNED(sg->offset, sizeof(u32)))
243*9e054ec2SFabien DESSENNE 			return -EINVAL;
244*9e054ec2SFabien DESSENNE 
245*9e054ec2SFabien DESSENNE 		if (!IS_ALIGNED(sg->length, align))
246*9e054ec2SFabien DESSENNE 			return -EINVAL;
247*9e054ec2SFabien DESSENNE 
248*9e054ec2SFabien DESSENNE 		len += sg->length;
249*9e054ec2SFabien DESSENNE 		sg = sg_next(sg);
250*9e054ec2SFabien DESSENNE 	}
251*9e054ec2SFabien DESSENNE 
252*9e054ec2SFabien DESSENNE 	if (len != total)
253*9e054ec2SFabien DESSENNE 		return -EINVAL;
254*9e054ec2SFabien DESSENNE 
255*9e054ec2SFabien DESSENNE 	return 0;
256*9e054ec2SFabien DESSENNE }
257*9e054ec2SFabien DESSENNE 
258*9e054ec2SFabien DESSENNE static int stm32_cryp_check_io_aligned(struct stm32_cryp *cryp)
259*9e054ec2SFabien DESSENNE {
260*9e054ec2SFabien DESSENNE 	int ret;
261*9e054ec2SFabien DESSENNE 
262*9e054ec2SFabien DESSENNE 	ret = stm32_cryp_check_aligned(cryp->in_sg, cryp->total_in,
263*9e054ec2SFabien DESSENNE 				       cryp->hw_blocksize);
264*9e054ec2SFabien DESSENNE 	if (ret)
265*9e054ec2SFabien DESSENNE 		return ret;
266*9e054ec2SFabien DESSENNE 
267*9e054ec2SFabien DESSENNE 	ret = stm32_cryp_check_aligned(cryp->out_sg, cryp->total_out,
268*9e054ec2SFabien DESSENNE 				       cryp->hw_blocksize);
269*9e054ec2SFabien DESSENNE 
270*9e054ec2SFabien DESSENNE 	return ret;
271*9e054ec2SFabien DESSENNE }
272*9e054ec2SFabien DESSENNE 
273*9e054ec2SFabien DESSENNE static void sg_copy_buf(void *buf, struct scatterlist *sg,
274*9e054ec2SFabien DESSENNE 			unsigned int start, unsigned int nbytes, int out)
275*9e054ec2SFabien DESSENNE {
276*9e054ec2SFabien DESSENNE 	struct scatter_walk walk;
277*9e054ec2SFabien DESSENNE 
278*9e054ec2SFabien DESSENNE 	if (!nbytes)
279*9e054ec2SFabien DESSENNE 		return;
280*9e054ec2SFabien DESSENNE 
281*9e054ec2SFabien DESSENNE 	scatterwalk_start(&walk, sg);
282*9e054ec2SFabien DESSENNE 	scatterwalk_advance(&walk, start);
283*9e054ec2SFabien DESSENNE 	scatterwalk_copychunks(buf, &walk, nbytes, out);
284*9e054ec2SFabien DESSENNE 	scatterwalk_done(&walk, out, 0);
285*9e054ec2SFabien DESSENNE }
286*9e054ec2SFabien DESSENNE 
287*9e054ec2SFabien DESSENNE static int stm32_cryp_copy_sgs(struct stm32_cryp *cryp)
288*9e054ec2SFabien DESSENNE {
289*9e054ec2SFabien DESSENNE 	void *buf_in, *buf_out;
290*9e054ec2SFabien DESSENNE 	int pages, total_in, total_out;
291*9e054ec2SFabien DESSENNE 
292*9e054ec2SFabien DESSENNE 	if (!stm32_cryp_check_io_aligned(cryp)) {
293*9e054ec2SFabien DESSENNE 		cryp->sgs_copied = 0;
294*9e054ec2SFabien DESSENNE 		return 0;
295*9e054ec2SFabien DESSENNE 	}
296*9e054ec2SFabien DESSENNE 
297*9e054ec2SFabien DESSENNE 	total_in = ALIGN(cryp->total_in, cryp->hw_blocksize);
298*9e054ec2SFabien DESSENNE 	pages = total_in ? get_order(total_in) : 1;
299*9e054ec2SFabien DESSENNE 	buf_in = (void *)__get_free_pages(GFP_ATOMIC, pages);
300*9e054ec2SFabien DESSENNE 
301*9e054ec2SFabien DESSENNE 	total_out = ALIGN(cryp->total_out, cryp->hw_blocksize);
302*9e054ec2SFabien DESSENNE 	pages = total_out ? get_order(total_out) : 1;
303*9e054ec2SFabien DESSENNE 	buf_out = (void *)__get_free_pages(GFP_ATOMIC, pages);
304*9e054ec2SFabien DESSENNE 
305*9e054ec2SFabien DESSENNE 	if (!buf_in || !buf_out) {
306*9e054ec2SFabien DESSENNE 		dev_err(cryp->dev, "Can't allocate pages when unaligned\n");
307*9e054ec2SFabien DESSENNE 		cryp->sgs_copied = 0;
308*9e054ec2SFabien DESSENNE 		return -EFAULT;
309*9e054ec2SFabien DESSENNE 	}
310*9e054ec2SFabien DESSENNE 
311*9e054ec2SFabien DESSENNE 	sg_copy_buf(buf_in, cryp->in_sg, 0, cryp->total_in, 0);
312*9e054ec2SFabien DESSENNE 
313*9e054ec2SFabien DESSENNE 	sg_init_one(&cryp->in_sgl, buf_in, total_in);
314*9e054ec2SFabien DESSENNE 	cryp->in_sg = &cryp->in_sgl;
315*9e054ec2SFabien DESSENNE 	cryp->in_sg_len = 1;
316*9e054ec2SFabien DESSENNE 
317*9e054ec2SFabien DESSENNE 	sg_init_one(&cryp->out_sgl, buf_out, total_out);
318*9e054ec2SFabien DESSENNE 	cryp->out_sg_save = cryp->out_sg;
319*9e054ec2SFabien DESSENNE 	cryp->out_sg = &cryp->out_sgl;
320*9e054ec2SFabien DESSENNE 	cryp->out_sg_len = 1;
321*9e054ec2SFabien DESSENNE 
322*9e054ec2SFabien DESSENNE 	cryp->sgs_copied = 1;
323*9e054ec2SFabien DESSENNE 
324*9e054ec2SFabien DESSENNE 	return 0;
325*9e054ec2SFabien DESSENNE }
326*9e054ec2SFabien DESSENNE 
327*9e054ec2SFabien DESSENNE static void stm32_cryp_hw_write_iv(struct stm32_cryp *cryp, u32 *iv)
328*9e054ec2SFabien DESSENNE {
329*9e054ec2SFabien DESSENNE 	if (!iv)
330*9e054ec2SFabien DESSENNE 		return;
331*9e054ec2SFabien DESSENNE 
332*9e054ec2SFabien DESSENNE 	stm32_cryp_write(cryp, CRYP_IV0LR, cpu_to_be32(*iv++));
333*9e054ec2SFabien DESSENNE 	stm32_cryp_write(cryp, CRYP_IV0RR, cpu_to_be32(*iv++));
334*9e054ec2SFabien DESSENNE 
335*9e054ec2SFabien DESSENNE 	if (is_aes(cryp)) {
336*9e054ec2SFabien DESSENNE 		stm32_cryp_write(cryp, CRYP_IV1LR, cpu_to_be32(*iv++));
337*9e054ec2SFabien DESSENNE 		stm32_cryp_write(cryp, CRYP_IV1RR, cpu_to_be32(*iv++));
338*9e054ec2SFabien DESSENNE 	}
339*9e054ec2SFabien DESSENNE }
340*9e054ec2SFabien DESSENNE 
341*9e054ec2SFabien DESSENNE static void stm32_cryp_hw_write_key(struct stm32_cryp *c)
342*9e054ec2SFabien DESSENNE {
343*9e054ec2SFabien DESSENNE 	unsigned int i;
344*9e054ec2SFabien DESSENNE 	int r_id;
345*9e054ec2SFabien DESSENNE 
346*9e054ec2SFabien DESSENNE 	if (is_des(c)) {
347*9e054ec2SFabien DESSENNE 		stm32_cryp_write(c, CRYP_K1LR, cpu_to_be32(c->ctx->key[0]));
348*9e054ec2SFabien DESSENNE 		stm32_cryp_write(c, CRYP_K1RR, cpu_to_be32(c->ctx->key[1]));
349*9e054ec2SFabien DESSENNE 	} else {
350*9e054ec2SFabien DESSENNE 		r_id = CRYP_K3RR;
351*9e054ec2SFabien DESSENNE 		for (i = c->ctx->keylen / sizeof(u32); i > 0; i--, r_id -= 4)
352*9e054ec2SFabien DESSENNE 			stm32_cryp_write(c, r_id,
353*9e054ec2SFabien DESSENNE 					 cpu_to_be32(c->ctx->key[i - 1]));
354*9e054ec2SFabien DESSENNE 	}
355*9e054ec2SFabien DESSENNE }
356*9e054ec2SFabien DESSENNE 
357*9e054ec2SFabien DESSENNE static u32 stm32_cryp_get_hw_mode(struct stm32_cryp *cryp)
358*9e054ec2SFabien DESSENNE {
359*9e054ec2SFabien DESSENNE 	if (is_aes(cryp) && is_ecb(cryp))
360*9e054ec2SFabien DESSENNE 		return CR_AES_ECB;
361*9e054ec2SFabien DESSENNE 
362*9e054ec2SFabien DESSENNE 	if (is_aes(cryp) && is_cbc(cryp))
363*9e054ec2SFabien DESSENNE 		return CR_AES_CBC;
364*9e054ec2SFabien DESSENNE 
365*9e054ec2SFabien DESSENNE 	if (is_aes(cryp) && is_ctr(cryp))
366*9e054ec2SFabien DESSENNE 		return CR_AES_CTR;
367*9e054ec2SFabien DESSENNE 
368*9e054ec2SFabien DESSENNE 	if (is_des(cryp) && is_ecb(cryp))
369*9e054ec2SFabien DESSENNE 		return CR_DES_ECB;
370*9e054ec2SFabien DESSENNE 
371*9e054ec2SFabien DESSENNE 	if (is_des(cryp) && is_cbc(cryp))
372*9e054ec2SFabien DESSENNE 		return CR_DES_CBC;
373*9e054ec2SFabien DESSENNE 
374*9e054ec2SFabien DESSENNE 	if (is_tdes(cryp) && is_ecb(cryp))
375*9e054ec2SFabien DESSENNE 		return CR_TDES_ECB;
376*9e054ec2SFabien DESSENNE 
377*9e054ec2SFabien DESSENNE 	if (is_tdes(cryp) && is_cbc(cryp))
378*9e054ec2SFabien DESSENNE 		return CR_TDES_CBC;
379*9e054ec2SFabien DESSENNE 
380*9e054ec2SFabien DESSENNE 	dev_err(cryp->dev, "Unknown mode\n");
381*9e054ec2SFabien DESSENNE 	return CR_AES_UNKNOWN;
382*9e054ec2SFabien DESSENNE }
383*9e054ec2SFabien DESSENNE 
384*9e054ec2SFabien DESSENNE static int stm32_cryp_hw_init(struct stm32_cryp *cryp)
385*9e054ec2SFabien DESSENNE {
386*9e054ec2SFabien DESSENNE 	int ret;
387*9e054ec2SFabien DESSENNE 	u32 cfg, hw_mode;
388*9e054ec2SFabien DESSENNE 
389*9e054ec2SFabien DESSENNE 	/* Disable interrupt */
390*9e054ec2SFabien DESSENNE 	stm32_cryp_write(cryp, CRYP_IMSCR, 0);
391*9e054ec2SFabien DESSENNE 
392*9e054ec2SFabien DESSENNE 	/* Set key */
393*9e054ec2SFabien DESSENNE 	stm32_cryp_hw_write_key(cryp);
394*9e054ec2SFabien DESSENNE 
395*9e054ec2SFabien DESSENNE 	/* Set configuration */
396*9e054ec2SFabien DESSENNE 	cfg = CR_DATA8 | CR_FFLUSH;
397*9e054ec2SFabien DESSENNE 
398*9e054ec2SFabien DESSENNE 	switch (cryp->ctx->keylen) {
399*9e054ec2SFabien DESSENNE 	case AES_KEYSIZE_128:
400*9e054ec2SFabien DESSENNE 		cfg |= CR_KEY128;
401*9e054ec2SFabien DESSENNE 		break;
402*9e054ec2SFabien DESSENNE 
403*9e054ec2SFabien DESSENNE 	case AES_KEYSIZE_192:
404*9e054ec2SFabien DESSENNE 		cfg |= CR_KEY192;
405*9e054ec2SFabien DESSENNE 		break;
406*9e054ec2SFabien DESSENNE 
407*9e054ec2SFabien DESSENNE 	default:
408*9e054ec2SFabien DESSENNE 	case AES_KEYSIZE_256:
409*9e054ec2SFabien DESSENNE 		cfg |= CR_KEY256;
410*9e054ec2SFabien DESSENNE 		break;
411*9e054ec2SFabien DESSENNE 	}
412*9e054ec2SFabien DESSENNE 
413*9e054ec2SFabien DESSENNE 	hw_mode = stm32_cryp_get_hw_mode(cryp);
414*9e054ec2SFabien DESSENNE 	if (hw_mode == CR_AES_UNKNOWN)
415*9e054ec2SFabien DESSENNE 		return -EINVAL;
416*9e054ec2SFabien DESSENNE 
417*9e054ec2SFabien DESSENNE 	/* AES ECB/CBC decrypt: run key preparation first */
418*9e054ec2SFabien DESSENNE 	if (is_decrypt(cryp) &&
419*9e054ec2SFabien DESSENNE 	    ((hw_mode == CR_AES_ECB) || (hw_mode == CR_AES_CBC))) {
420*9e054ec2SFabien DESSENNE 		stm32_cryp_write(cryp, CRYP_CR, cfg | CR_AES_KP | CR_CRYPEN);
421*9e054ec2SFabien DESSENNE 
422*9e054ec2SFabien DESSENNE 		/* Wait for end of processing */
423*9e054ec2SFabien DESSENNE 		ret = stm32_cryp_wait_busy(cryp);
424*9e054ec2SFabien DESSENNE 		if (ret) {
425*9e054ec2SFabien DESSENNE 			dev_err(cryp->dev, "Timeout (key preparation)\n");
426*9e054ec2SFabien DESSENNE 			return ret;
427*9e054ec2SFabien DESSENNE 		}
428*9e054ec2SFabien DESSENNE 	}
429*9e054ec2SFabien DESSENNE 
430*9e054ec2SFabien DESSENNE 	cfg |= hw_mode;
431*9e054ec2SFabien DESSENNE 
432*9e054ec2SFabien DESSENNE 	if (is_decrypt(cryp))
433*9e054ec2SFabien DESSENNE 		cfg |= CR_DEC_NOT_ENC;
434*9e054ec2SFabien DESSENNE 
435*9e054ec2SFabien DESSENNE 	/* Apply config and flush (valid when CRYPEN = 0) */
436*9e054ec2SFabien DESSENNE 	stm32_cryp_write(cryp, CRYP_CR, cfg);
437*9e054ec2SFabien DESSENNE 
438*9e054ec2SFabien DESSENNE 	switch (hw_mode) {
439*9e054ec2SFabien DESSENNE 	case CR_DES_CBC:
440*9e054ec2SFabien DESSENNE 	case CR_TDES_CBC:
441*9e054ec2SFabien DESSENNE 	case CR_AES_CBC:
442*9e054ec2SFabien DESSENNE 	case CR_AES_CTR:
443*9e054ec2SFabien DESSENNE 		stm32_cryp_hw_write_iv(cryp, (u32 *)cryp->req->info);
444*9e054ec2SFabien DESSENNE 		break;
445*9e054ec2SFabien DESSENNE 
446*9e054ec2SFabien DESSENNE 	default:
447*9e054ec2SFabien DESSENNE 		break;
448*9e054ec2SFabien DESSENNE 	}
449*9e054ec2SFabien DESSENNE 
450*9e054ec2SFabien DESSENNE 	/* Enable now */
451*9e054ec2SFabien DESSENNE 	cfg |= CR_CRYPEN;
452*9e054ec2SFabien DESSENNE 
453*9e054ec2SFabien DESSENNE 	stm32_cryp_write(cryp, CRYP_CR, cfg);
454*9e054ec2SFabien DESSENNE 
455*9e054ec2SFabien DESSENNE 	return 0;
456*9e054ec2SFabien DESSENNE }
457*9e054ec2SFabien DESSENNE 
458*9e054ec2SFabien DESSENNE static void stm32_cryp_finish_req(struct stm32_cryp *cryp)
459*9e054ec2SFabien DESSENNE {
460*9e054ec2SFabien DESSENNE 	int err = 0;
461*9e054ec2SFabien DESSENNE 
462*9e054ec2SFabien DESSENNE 	if (cryp->sgs_copied) {
463*9e054ec2SFabien DESSENNE 		void *buf_in, *buf_out;
464*9e054ec2SFabien DESSENNE 		int pages, len;
465*9e054ec2SFabien DESSENNE 
466*9e054ec2SFabien DESSENNE 		buf_in = sg_virt(&cryp->in_sgl);
467*9e054ec2SFabien DESSENNE 		buf_out = sg_virt(&cryp->out_sgl);
468*9e054ec2SFabien DESSENNE 
469*9e054ec2SFabien DESSENNE 		sg_copy_buf(buf_out, cryp->out_sg_save, 0,
470*9e054ec2SFabien DESSENNE 			    cryp->total_out_save, 1);
471*9e054ec2SFabien DESSENNE 
472*9e054ec2SFabien DESSENNE 		len = ALIGN(cryp->total_in_save, cryp->hw_blocksize);
473*9e054ec2SFabien DESSENNE 		pages = len ? get_order(len) : 1;
474*9e054ec2SFabien DESSENNE 		free_pages((unsigned long)buf_in, pages);
475*9e054ec2SFabien DESSENNE 
476*9e054ec2SFabien DESSENNE 		len = ALIGN(cryp->total_out_save, cryp->hw_blocksize);
477*9e054ec2SFabien DESSENNE 		pages = len ? get_order(len) : 1;
478*9e054ec2SFabien DESSENNE 		free_pages((unsigned long)buf_out, pages);
479*9e054ec2SFabien DESSENNE 	}
480*9e054ec2SFabien DESSENNE 
481*9e054ec2SFabien DESSENNE 	crypto_finalize_cipher_request(cryp->engine, cryp->req, err);
482*9e054ec2SFabien DESSENNE 	cryp->req = NULL;
483*9e054ec2SFabien DESSENNE 
484*9e054ec2SFabien DESSENNE 	memset(cryp->ctx->key, 0, cryp->ctx->keylen);
485*9e054ec2SFabien DESSENNE 
486*9e054ec2SFabien DESSENNE 	mutex_unlock(&cryp->lock);
487*9e054ec2SFabien DESSENNE }
488*9e054ec2SFabien DESSENNE 
489*9e054ec2SFabien DESSENNE static int stm32_cryp_cpu_start(struct stm32_cryp *cryp)
490*9e054ec2SFabien DESSENNE {
491*9e054ec2SFabien DESSENNE 	/* Enable interrupt and let the IRQ handler do everything */
492*9e054ec2SFabien DESSENNE 	stm32_cryp_write(cryp, CRYP_IMSCR, IMSCR_IN | IMSCR_OUT);
493*9e054ec2SFabien DESSENNE 
494*9e054ec2SFabien DESSENNE 	return 0;
495*9e054ec2SFabien DESSENNE }
496*9e054ec2SFabien DESSENNE 
497*9e054ec2SFabien DESSENNE static int stm32_cryp_cra_init(struct crypto_tfm *tfm)
498*9e054ec2SFabien DESSENNE {
499*9e054ec2SFabien DESSENNE 	tfm->crt_ablkcipher.reqsize = sizeof(struct stm32_cryp_reqctx);
500*9e054ec2SFabien DESSENNE 
501*9e054ec2SFabien DESSENNE 	return 0;
502*9e054ec2SFabien DESSENNE }
503*9e054ec2SFabien DESSENNE 
504*9e054ec2SFabien DESSENNE static int stm32_cryp_crypt(struct ablkcipher_request *req, unsigned long mode)
505*9e054ec2SFabien DESSENNE {
506*9e054ec2SFabien DESSENNE 	struct stm32_cryp_ctx *ctx = crypto_ablkcipher_ctx(
507*9e054ec2SFabien DESSENNE 			crypto_ablkcipher_reqtfm(req));
508*9e054ec2SFabien DESSENNE 	struct stm32_cryp_reqctx *rctx = ablkcipher_request_ctx(req);
509*9e054ec2SFabien DESSENNE 	struct stm32_cryp *cryp = stm32_cryp_find_dev(ctx);
510*9e054ec2SFabien DESSENNE 
511*9e054ec2SFabien DESSENNE 	if (!cryp)
512*9e054ec2SFabien DESSENNE 		return -ENODEV;
513*9e054ec2SFabien DESSENNE 
514*9e054ec2SFabien DESSENNE 	rctx->mode = mode;
515*9e054ec2SFabien DESSENNE 
516*9e054ec2SFabien DESSENNE 	return crypto_transfer_cipher_request_to_engine(cryp->engine, req);
517*9e054ec2SFabien DESSENNE }
518*9e054ec2SFabien DESSENNE 
519*9e054ec2SFabien DESSENNE static int stm32_cryp_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
520*9e054ec2SFabien DESSENNE 			     unsigned int keylen)
521*9e054ec2SFabien DESSENNE {
522*9e054ec2SFabien DESSENNE 	struct stm32_cryp_ctx *ctx = crypto_ablkcipher_ctx(tfm);
523*9e054ec2SFabien DESSENNE 
524*9e054ec2SFabien DESSENNE 	memcpy(ctx->key, key, keylen);
525*9e054ec2SFabien DESSENNE 	ctx->keylen = keylen;
526*9e054ec2SFabien DESSENNE 
527*9e054ec2SFabien DESSENNE 	return 0;
528*9e054ec2SFabien DESSENNE }
529*9e054ec2SFabien DESSENNE 
530*9e054ec2SFabien DESSENNE static int stm32_cryp_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
531*9e054ec2SFabien DESSENNE 				 unsigned int keylen)
532*9e054ec2SFabien DESSENNE {
533*9e054ec2SFabien DESSENNE 	if (keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_192 &&
534*9e054ec2SFabien DESSENNE 	    keylen != AES_KEYSIZE_256)
535*9e054ec2SFabien DESSENNE 		return -EINVAL;
536*9e054ec2SFabien DESSENNE 	else
537*9e054ec2SFabien DESSENNE 		return stm32_cryp_setkey(tfm, key, keylen);
538*9e054ec2SFabien DESSENNE }
539*9e054ec2SFabien DESSENNE 
540*9e054ec2SFabien DESSENNE static int stm32_cryp_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
541*9e054ec2SFabien DESSENNE 				 unsigned int keylen)
542*9e054ec2SFabien DESSENNE {
543*9e054ec2SFabien DESSENNE 	if (keylen != DES_KEY_SIZE)
544*9e054ec2SFabien DESSENNE 		return -EINVAL;
545*9e054ec2SFabien DESSENNE 	else
546*9e054ec2SFabien DESSENNE 		return stm32_cryp_setkey(tfm, key, keylen);
547*9e054ec2SFabien DESSENNE }
548*9e054ec2SFabien DESSENNE 
549*9e054ec2SFabien DESSENNE static int stm32_cryp_tdes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
550*9e054ec2SFabien DESSENNE 				  unsigned int keylen)
551*9e054ec2SFabien DESSENNE {
552*9e054ec2SFabien DESSENNE 	if (keylen != (3 * DES_KEY_SIZE))
553*9e054ec2SFabien DESSENNE 		return -EINVAL;
554*9e054ec2SFabien DESSENNE 	else
555*9e054ec2SFabien DESSENNE 		return stm32_cryp_setkey(tfm, key, keylen);
556*9e054ec2SFabien DESSENNE }
557*9e054ec2SFabien DESSENNE 
558*9e054ec2SFabien DESSENNE static int stm32_cryp_aes_ecb_encrypt(struct ablkcipher_request *req)
559*9e054ec2SFabien DESSENNE {
560*9e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_AES | FLG_ECB | FLG_ENCRYPT);
561*9e054ec2SFabien DESSENNE }
562*9e054ec2SFabien DESSENNE 
563*9e054ec2SFabien DESSENNE static int stm32_cryp_aes_ecb_decrypt(struct ablkcipher_request *req)
564*9e054ec2SFabien DESSENNE {
565*9e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_AES | FLG_ECB);
566*9e054ec2SFabien DESSENNE }
567*9e054ec2SFabien DESSENNE 
568*9e054ec2SFabien DESSENNE static int stm32_cryp_aes_cbc_encrypt(struct ablkcipher_request *req)
569*9e054ec2SFabien DESSENNE {
570*9e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_AES | FLG_CBC | FLG_ENCRYPT);
571*9e054ec2SFabien DESSENNE }
572*9e054ec2SFabien DESSENNE 
573*9e054ec2SFabien DESSENNE static int stm32_cryp_aes_cbc_decrypt(struct ablkcipher_request *req)
574*9e054ec2SFabien DESSENNE {
575*9e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_AES | FLG_CBC);
576*9e054ec2SFabien DESSENNE }
577*9e054ec2SFabien DESSENNE 
578*9e054ec2SFabien DESSENNE static int stm32_cryp_aes_ctr_encrypt(struct ablkcipher_request *req)
579*9e054ec2SFabien DESSENNE {
580*9e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_AES | FLG_CTR | FLG_ENCRYPT);
581*9e054ec2SFabien DESSENNE }
582*9e054ec2SFabien DESSENNE 
583*9e054ec2SFabien DESSENNE static int stm32_cryp_aes_ctr_decrypt(struct ablkcipher_request *req)
584*9e054ec2SFabien DESSENNE {
585*9e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_AES | FLG_CTR);
586*9e054ec2SFabien DESSENNE }
587*9e054ec2SFabien DESSENNE 
588*9e054ec2SFabien DESSENNE static int stm32_cryp_des_ecb_encrypt(struct ablkcipher_request *req)
589*9e054ec2SFabien DESSENNE {
590*9e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_DES | FLG_ECB | FLG_ENCRYPT);
591*9e054ec2SFabien DESSENNE }
592*9e054ec2SFabien DESSENNE 
593*9e054ec2SFabien DESSENNE static int stm32_cryp_des_ecb_decrypt(struct ablkcipher_request *req)
594*9e054ec2SFabien DESSENNE {
595*9e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_DES | FLG_ECB);
596*9e054ec2SFabien DESSENNE }
597*9e054ec2SFabien DESSENNE 
598*9e054ec2SFabien DESSENNE static int stm32_cryp_des_cbc_encrypt(struct ablkcipher_request *req)
599*9e054ec2SFabien DESSENNE {
600*9e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_DES | FLG_CBC | FLG_ENCRYPT);
601*9e054ec2SFabien DESSENNE }
602*9e054ec2SFabien DESSENNE 
603*9e054ec2SFabien DESSENNE static int stm32_cryp_des_cbc_decrypt(struct ablkcipher_request *req)
604*9e054ec2SFabien DESSENNE {
605*9e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_DES | FLG_CBC);
606*9e054ec2SFabien DESSENNE }
607*9e054ec2SFabien DESSENNE 
608*9e054ec2SFabien DESSENNE static int stm32_cryp_tdes_ecb_encrypt(struct ablkcipher_request *req)
609*9e054ec2SFabien DESSENNE {
610*9e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_TDES | FLG_ECB | FLG_ENCRYPT);
611*9e054ec2SFabien DESSENNE }
612*9e054ec2SFabien DESSENNE 
613*9e054ec2SFabien DESSENNE static int stm32_cryp_tdes_ecb_decrypt(struct ablkcipher_request *req)
614*9e054ec2SFabien DESSENNE {
615*9e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_TDES | FLG_ECB);
616*9e054ec2SFabien DESSENNE }
617*9e054ec2SFabien DESSENNE 
618*9e054ec2SFabien DESSENNE static int stm32_cryp_tdes_cbc_encrypt(struct ablkcipher_request *req)
619*9e054ec2SFabien DESSENNE {
620*9e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_TDES | FLG_CBC | FLG_ENCRYPT);
621*9e054ec2SFabien DESSENNE }
622*9e054ec2SFabien DESSENNE 
623*9e054ec2SFabien DESSENNE static int stm32_cryp_tdes_cbc_decrypt(struct ablkcipher_request *req)
624*9e054ec2SFabien DESSENNE {
625*9e054ec2SFabien DESSENNE 	return stm32_cryp_crypt(req, FLG_TDES | FLG_CBC);
626*9e054ec2SFabien DESSENNE }
627*9e054ec2SFabien DESSENNE 
628*9e054ec2SFabien DESSENNE static int stm32_cryp_prepare_req(struct crypto_engine *engine,
629*9e054ec2SFabien DESSENNE 				  struct ablkcipher_request *req)
630*9e054ec2SFabien DESSENNE {
631*9e054ec2SFabien DESSENNE 	struct stm32_cryp_ctx *ctx;
632*9e054ec2SFabien DESSENNE 	struct stm32_cryp *cryp;
633*9e054ec2SFabien DESSENNE 	struct stm32_cryp_reqctx *rctx;
634*9e054ec2SFabien DESSENNE 	int ret;
635*9e054ec2SFabien DESSENNE 
636*9e054ec2SFabien DESSENNE 	if (!req)
637*9e054ec2SFabien DESSENNE 		return -EINVAL;
638*9e054ec2SFabien DESSENNE 
639*9e054ec2SFabien DESSENNE 	ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(req));
640*9e054ec2SFabien DESSENNE 
641*9e054ec2SFabien DESSENNE 	cryp = ctx->cryp;
642*9e054ec2SFabien DESSENNE 
643*9e054ec2SFabien DESSENNE 	if (!cryp)
644*9e054ec2SFabien DESSENNE 		return -ENODEV;
645*9e054ec2SFabien DESSENNE 
646*9e054ec2SFabien DESSENNE 	mutex_lock(&cryp->lock);
647*9e054ec2SFabien DESSENNE 
648*9e054ec2SFabien DESSENNE 	rctx = ablkcipher_request_ctx(req);
649*9e054ec2SFabien DESSENNE 	rctx->mode &= FLG_MODE_MASK;
650*9e054ec2SFabien DESSENNE 
651*9e054ec2SFabien DESSENNE 	ctx->cryp = cryp;
652*9e054ec2SFabien DESSENNE 
653*9e054ec2SFabien DESSENNE 	cryp->flags = (cryp->flags & ~FLG_MODE_MASK) | rctx->mode;
654*9e054ec2SFabien DESSENNE 	cryp->hw_blocksize = is_aes(cryp) ? AES_BLOCK_SIZE : DES_BLOCK_SIZE;
655*9e054ec2SFabien DESSENNE 	cryp->ctx = ctx;
656*9e054ec2SFabien DESSENNE 
657*9e054ec2SFabien DESSENNE 	cryp->req = req;
658*9e054ec2SFabien DESSENNE 	cryp->total_in = req->nbytes;
659*9e054ec2SFabien DESSENNE 	cryp->total_out = cryp->total_in;
660*9e054ec2SFabien DESSENNE 
661*9e054ec2SFabien DESSENNE 	cryp->total_in_save = cryp->total_in;
662*9e054ec2SFabien DESSENNE 	cryp->total_out_save = cryp->total_out;
663*9e054ec2SFabien DESSENNE 
664*9e054ec2SFabien DESSENNE 	cryp->in_sg = req->src;
665*9e054ec2SFabien DESSENNE 	cryp->out_sg = req->dst;
666*9e054ec2SFabien DESSENNE 	cryp->out_sg_save = cryp->out_sg;
667*9e054ec2SFabien DESSENNE 
668*9e054ec2SFabien DESSENNE 	cryp->in_sg_len = sg_nents_for_len(cryp->in_sg, cryp->total_in);
669*9e054ec2SFabien DESSENNE 	if (cryp->in_sg_len < 0) {
670*9e054ec2SFabien DESSENNE 		dev_err(cryp->dev, "Cannot get in_sg_len\n");
671*9e054ec2SFabien DESSENNE 		ret = cryp->in_sg_len;
672*9e054ec2SFabien DESSENNE 		goto out;
673*9e054ec2SFabien DESSENNE 	}
674*9e054ec2SFabien DESSENNE 
675*9e054ec2SFabien DESSENNE 	cryp->out_sg_len = sg_nents_for_len(cryp->out_sg, cryp->total_out);
676*9e054ec2SFabien DESSENNE 	if (cryp->out_sg_len < 0) {
677*9e054ec2SFabien DESSENNE 		dev_err(cryp->dev, "Cannot get out_sg_len\n");
678*9e054ec2SFabien DESSENNE 		ret = cryp->out_sg_len;
679*9e054ec2SFabien DESSENNE 		goto out;
680*9e054ec2SFabien DESSENNE 	}
681*9e054ec2SFabien DESSENNE 
682*9e054ec2SFabien DESSENNE 	ret = stm32_cryp_copy_sgs(cryp);
683*9e054ec2SFabien DESSENNE 	if (ret)
684*9e054ec2SFabien DESSENNE 		goto out;
685*9e054ec2SFabien DESSENNE 
686*9e054ec2SFabien DESSENNE 	scatterwalk_start(&cryp->in_walk, cryp->in_sg);
687*9e054ec2SFabien DESSENNE 	scatterwalk_start(&cryp->out_walk, cryp->out_sg);
688*9e054ec2SFabien DESSENNE 
689*9e054ec2SFabien DESSENNE 	ret = stm32_cryp_hw_init(cryp);
690*9e054ec2SFabien DESSENNE out:
691*9e054ec2SFabien DESSENNE 	if (ret)
692*9e054ec2SFabien DESSENNE 		mutex_unlock(&cryp->lock);
693*9e054ec2SFabien DESSENNE 
694*9e054ec2SFabien DESSENNE 	return ret;
695*9e054ec2SFabien DESSENNE }
696*9e054ec2SFabien DESSENNE 
697*9e054ec2SFabien DESSENNE static int stm32_cryp_prepare_cipher_req(struct crypto_engine *engine,
698*9e054ec2SFabien DESSENNE 					 struct ablkcipher_request *req)
699*9e054ec2SFabien DESSENNE {
700*9e054ec2SFabien DESSENNE 	return stm32_cryp_prepare_req(engine, req);
701*9e054ec2SFabien DESSENNE }
702*9e054ec2SFabien DESSENNE 
703*9e054ec2SFabien DESSENNE static int stm32_cryp_cipher_one_req(struct crypto_engine *engine,
704*9e054ec2SFabien DESSENNE 				     struct ablkcipher_request *req)
705*9e054ec2SFabien DESSENNE {
706*9e054ec2SFabien DESSENNE 	struct stm32_cryp_ctx *ctx = crypto_ablkcipher_ctx(
707*9e054ec2SFabien DESSENNE 			crypto_ablkcipher_reqtfm(req));
708*9e054ec2SFabien DESSENNE 	struct stm32_cryp *cryp = ctx->cryp;
709*9e054ec2SFabien DESSENNE 
710*9e054ec2SFabien DESSENNE 	if (!cryp)
711*9e054ec2SFabien DESSENNE 		return -ENODEV;
712*9e054ec2SFabien DESSENNE 
713*9e054ec2SFabien DESSENNE 	return stm32_cryp_cpu_start(cryp);
714*9e054ec2SFabien DESSENNE }
715*9e054ec2SFabien DESSENNE 
716*9e054ec2SFabien DESSENNE static u32 *stm32_cryp_next_out(struct stm32_cryp *cryp, u32 *dst,
717*9e054ec2SFabien DESSENNE 				unsigned int n)
718*9e054ec2SFabien DESSENNE {
719*9e054ec2SFabien DESSENNE 	scatterwalk_advance(&cryp->out_walk, n);
720*9e054ec2SFabien DESSENNE 
721*9e054ec2SFabien DESSENNE 	if (unlikely(cryp->out_sg->length == _walked_out)) {
722*9e054ec2SFabien DESSENNE 		cryp->out_sg = sg_next(cryp->out_sg);
723*9e054ec2SFabien DESSENNE 		if (cryp->out_sg) {
724*9e054ec2SFabien DESSENNE 			scatterwalk_start(&cryp->out_walk, cryp->out_sg);
725*9e054ec2SFabien DESSENNE 			return (sg_virt(cryp->out_sg) + _walked_out);
726*9e054ec2SFabien DESSENNE 		}
727*9e054ec2SFabien DESSENNE 	}
728*9e054ec2SFabien DESSENNE 
729*9e054ec2SFabien DESSENNE 	return (u32 *)((u8 *)dst + n);
730*9e054ec2SFabien DESSENNE }
731*9e054ec2SFabien DESSENNE 
732*9e054ec2SFabien DESSENNE static u32 *stm32_cryp_next_in(struct stm32_cryp *cryp, u32 *src,
733*9e054ec2SFabien DESSENNE 			       unsigned int n)
734*9e054ec2SFabien DESSENNE {
735*9e054ec2SFabien DESSENNE 	scatterwalk_advance(&cryp->in_walk, n);
736*9e054ec2SFabien DESSENNE 
737*9e054ec2SFabien DESSENNE 	if (unlikely(cryp->in_sg->length == _walked_in)) {
738*9e054ec2SFabien DESSENNE 		cryp->in_sg = sg_next(cryp->in_sg);
739*9e054ec2SFabien DESSENNE 		if (cryp->in_sg) {
740*9e054ec2SFabien DESSENNE 			scatterwalk_start(&cryp->in_walk, cryp->in_sg);
741*9e054ec2SFabien DESSENNE 			return (sg_virt(cryp->in_sg) + _walked_in);
742*9e054ec2SFabien DESSENNE 		}
743*9e054ec2SFabien DESSENNE 	}
744*9e054ec2SFabien DESSENNE 
745*9e054ec2SFabien DESSENNE 	return (u32 *)((u8 *)src + n);
746*9e054ec2SFabien DESSENNE }
747*9e054ec2SFabien DESSENNE 
748*9e054ec2SFabien DESSENNE static void stm32_cryp_check_ctr_counter(struct stm32_cryp *cryp)
749*9e054ec2SFabien DESSENNE {
750*9e054ec2SFabien DESSENNE 	u32 cr;
751*9e054ec2SFabien DESSENNE 
752*9e054ec2SFabien DESSENNE 	if (unlikely(cryp->last_ctr[3] == 0xFFFFFFFF)) {
753*9e054ec2SFabien DESSENNE 		cryp->last_ctr[3] = 0;
754*9e054ec2SFabien DESSENNE 		cryp->last_ctr[2]++;
755*9e054ec2SFabien DESSENNE 		if (!cryp->last_ctr[2]) {
756*9e054ec2SFabien DESSENNE 			cryp->last_ctr[1]++;
757*9e054ec2SFabien DESSENNE 			if (!cryp->last_ctr[1])
758*9e054ec2SFabien DESSENNE 				cryp->last_ctr[0]++;
759*9e054ec2SFabien DESSENNE 		}
760*9e054ec2SFabien DESSENNE 
761*9e054ec2SFabien DESSENNE 		cr = stm32_cryp_read(cryp, CRYP_CR);
762*9e054ec2SFabien DESSENNE 		stm32_cryp_write(cryp, CRYP_CR, cr & ~CR_CRYPEN);
763*9e054ec2SFabien DESSENNE 
764*9e054ec2SFabien DESSENNE 		stm32_cryp_hw_write_iv(cryp, (u32 *)cryp->last_ctr);
765*9e054ec2SFabien DESSENNE 
766*9e054ec2SFabien DESSENNE 		stm32_cryp_write(cryp, CRYP_CR, cr);
767*9e054ec2SFabien DESSENNE 	}
768*9e054ec2SFabien DESSENNE 
769*9e054ec2SFabien DESSENNE 	cryp->last_ctr[0] = stm32_cryp_read(cryp, CRYP_IV0LR);
770*9e054ec2SFabien DESSENNE 	cryp->last_ctr[1] = stm32_cryp_read(cryp, CRYP_IV0RR);
771*9e054ec2SFabien DESSENNE 	cryp->last_ctr[2] = stm32_cryp_read(cryp, CRYP_IV1LR);
772*9e054ec2SFabien DESSENNE 	cryp->last_ctr[3] = stm32_cryp_read(cryp, CRYP_IV1RR);
773*9e054ec2SFabien DESSENNE }
774*9e054ec2SFabien DESSENNE 
775*9e054ec2SFabien DESSENNE static bool stm32_cryp_irq_read_data(struct stm32_cryp *cryp)
776*9e054ec2SFabien DESSENNE {
777*9e054ec2SFabien DESSENNE 	unsigned int i, j;
778*9e054ec2SFabien DESSENNE 	u32 d32, *dst;
779*9e054ec2SFabien DESSENNE 	u8 *d8;
780*9e054ec2SFabien DESSENNE 
781*9e054ec2SFabien DESSENNE 	dst = sg_virt(cryp->out_sg) + _walked_out;
782*9e054ec2SFabien DESSENNE 
783*9e054ec2SFabien DESSENNE 	for (i = 0; i < cryp->hw_blocksize / sizeof(u32); i++) {
784*9e054ec2SFabien DESSENNE 		if (likely(cryp->total_out >= sizeof(u32))) {
785*9e054ec2SFabien DESSENNE 			/* Read a full u32 */
786*9e054ec2SFabien DESSENNE 			*dst = stm32_cryp_read(cryp, CRYP_DOUT);
787*9e054ec2SFabien DESSENNE 
788*9e054ec2SFabien DESSENNE 			dst = stm32_cryp_next_out(cryp, dst, sizeof(u32));
789*9e054ec2SFabien DESSENNE 			cryp->total_out -= sizeof(u32);
790*9e054ec2SFabien DESSENNE 		} else if (!cryp->total_out) {
791*9e054ec2SFabien DESSENNE 			/* Empty fifo out (data from input padding) */
792*9e054ec2SFabien DESSENNE 			d32 = stm32_cryp_read(cryp, CRYP_DOUT);
793*9e054ec2SFabien DESSENNE 		} else {
794*9e054ec2SFabien DESSENNE 			/* Read less than an u32 */
795*9e054ec2SFabien DESSENNE 			d32 = stm32_cryp_read(cryp, CRYP_DOUT);
796*9e054ec2SFabien DESSENNE 			d8 = (u8 *)&d32;
797*9e054ec2SFabien DESSENNE 
798*9e054ec2SFabien DESSENNE 			for (j = 0; j < cryp->total_out; j++) {
799*9e054ec2SFabien DESSENNE 				*((u8 *)dst) = *(d8++);
800*9e054ec2SFabien DESSENNE 				dst = stm32_cryp_next_out(cryp, dst, 1);
801*9e054ec2SFabien DESSENNE 			}
802*9e054ec2SFabien DESSENNE 			cryp->total_out = 0;
803*9e054ec2SFabien DESSENNE 		}
804*9e054ec2SFabien DESSENNE 	}
805*9e054ec2SFabien DESSENNE 
806*9e054ec2SFabien DESSENNE 	return !cryp->total_out || !cryp->total_in;
807*9e054ec2SFabien DESSENNE }
808*9e054ec2SFabien DESSENNE 
809*9e054ec2SFabien DESSENNE static void stm32_cryp_irq_write_block(struct stm32_cryp *cryp)
810*9e054ec2SFabien DESSENNE {
811*9e054ec2SFabien DESSENNE 	unsigned int i, j;
812*9e054ec2SFabien DESSENNE 	u32 *src;
813*9e054ec2SFabien DESSENNE 	u8 d8[4];
814*9e054ec2SFabien DESSENNE 
815*9e054ec2SFabien DESSENNE 	src = sg_virt(cryp->in_sg) + _walked_in;
816*9e054ec2SFabien DESSENNE 
817*9e054ec2SFabien DESSENNE 	for (i = 0; i < cryp->hw_blocksize / sizeof(u32); i++) {
818*9e054ec2SFabien DESSENNE 		if (likely(cryp->total_in >= sizeof(u32))) {
819*9e054ec2SFabien DESSENNE 			/* Write a full u32 */
820*9e054ec2SFabien DESSENNE 			stm32_cryp_write(cryp, CRYP_DIN, *src);
821*9e054ec2SFabien DESSENNE 
822*9e054ec2SFabien DESSENNE 			src = stm32_cryp_next_in(cryp, src, sizeof(u32));
823*9e054ec2SFabien DESSENNE 			cryp->total_in -= sizeof(u32);
824*9e054ec2SFabien DESSENNE 		} else if (!cryp->total_in) {
825*9e054ec2SFabien DESSENNE 			/* Write padding data */
826*9e054ec2SFabien DESSENNE 			stm32_cryp_write(cryp, CRYP_DIN, 0);
827*9e054ec2SFabien DESSENNE 		} else {
828*9e054ec2SFabien DESSENNE 			/* Write less than an u32 */
829*9e054ec2SFabien DESSENNE 			memset(d8, 0, sizeof(u32));
830*9e054ec2SFabien DESSENNE 			for (j = 0; j < cryp->total_in; j++) {
831*9e054ec2SFabien DESSENNE 				d8[j] = *((u8 *)src);
832*9e054ec2SFabien DESSENNE 				src = stm32_cryp_next_in(cryp, src, 1);
833*9e054ec2SFabien DESSENNE 			}
834*9e054ec2SFabien DESSENNE 
835*9e054ec2SFabien DESSENNE 			stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8);
836*9e054ec2SFabien DESSENNE 			cryp->total_in = 0;
837*9e054ec2SFabien DESSENNE 		}
838*9e054ec2SFabien DESSENNE 	}
839*9e054ec2SFabien DESSENNE }
840*9e054ec2SFabien DESSENNE 
841*9e054ec2SFabien DESSENNE static void stm32_cryp_irq_write_data(struct stm32_cryp *cryp)
842*9e054ec2SFabien DESSENNE {
843*9e054ec2SFabien DESSENNE 	if (unlikely(!cryp->total_in)) {
844*9e054ec2SFabien DESSENNE 		dev_warn(cryp->dev, "No more data to process\n");
845*9e054ec2SFabien DESSENNE 		return;
846*9e054ec2SFabien DESSENNE 	}
847*9e054ec2SFabien DESSENNE 
848*9e054ec2SFabien DESSENNE 	if (is_aes(cryp) && is_ctr(cryp))
849*9e054ec2SFabien DESSENNE 		stm32_cryp_check_ctr_counter(cryp);
850*9e054ec2SFabien DESSENNE 
851*9e054ec2SFabien DESSENNE 	stm32_cryp_irq_write_block(cryp);
852*9e054ec2SFabien DESSENNE }
853*9e054ec2SFabien DESSENNE 
854*9e054ec2SFabien DESSENNE static irqreturn_t stm32_cryp_irq_thread(int irq, void *arg)
855*9e054ec2SFabien DESSENNE {
856*9e054ec2SFabien DESSENNE 	struct stm32_cryp *cryp = arg;
857*9e054ec2SFabien DESSENNE 
858*9e054ec2SFabien DESSENNE 	if (cryp->irq_status & MISR_OUT)
859*9e054ec2SFabien DESSENNE 		/* Output FIFO IRQ: read data */
860*9e054ec2SFabien DESSENNE 		if (unlikely(stm32_cryp_irq_read_data(cryp))) {
861*9e054ec2SFabien DESSENNE 			/* All bytes processed, finish */
862*9e054ec2SFabien DESSENNE 			stm32_cryp_write(cryp, CRYP_IMSCR, 0);
863*9e054ec2SFabien DESSENNE 			stm32_cryp_finish_req(cryp);
864*9e054ec2SFabien DESSENNE 			return IRQ_HANDLED;
865*9e054ec2SFabien DESSENNE 		}
866*9e054ec2SFabien DESSENNE 
867*9e054ec2SFabien DESSENNE 	if (cryp->irq_status & MISR_IN) {
868*9e054ec2SFabien DESSENNE 		/* Input FIFO IRQ: write data */
869*9e054ec2SFabien DESSENNE 		stm32_cryp_irq_write_data(cryp);
870*9e054ec2SFabien DESSENNE 	}
871*9e054ec2SFabien DESSENNE 
872*9e054ec2SFabien DESSENNE 	return IRQ_HANDLED;
873*9e054ec2SFabien DESSENNE }
874*9e054ec2SFabien DESSENNE 
875*9e054ec2SFabien DESSENNE static irqreturn_t stm32_cryp_irq(int irq, void *arg)
876*9e054ec2SFabien DESSENNE {
877*9e054ec2SFabien DESSENNE 	struct stm32_cryp *cryp = arg;
878*9e054ec2SFabien DESSENNE 
879*9e054ec2SFabien DESSENNE 	cryp->irq_status = stm32_cryp_read(cryp, CRYP_MISR);
880*9e054ec2SFabien DESSENNE 
881*9e054ec2SFabien DESSENNE 	return IRQ_WAKE_THREAD;
882*9e054ec2SFabien DESSENNE }
883*9e054ec2SFabien DESSENNE 
884*9e054ec2SFabien DESSENNE static struct crypto_alg crypto_algs[] = {
885*9e054ec2SFabien DESSENNE {
886*9e054ec2SFabien DESSENNE 	.cra_name		= "ecb(aes)",
887*9e054ec2SFabien DESSENNE 	.cra_driver_name	= "stm32-ecb-aes",
888*9e054ec2SFabien DESSENNE 	.cra_priority		= 200,
889*9e054ec2SFabien DESSENNE 	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER |
890*9e054ec2SFabien DESSENNE 				  CRYPTO_ALG_ASYNC,
891*9e054ec2SFabien DESSENNE 	.cra_blocksize		= AES_BLOCK_SIZE,
892*9e054ec2SFabien DESSENNE 	.cra_ctxsize		= sizeof(struct stm32_cryp_ctx),
893*9e054ec2SFabien DESSENNE 	.cra_alignmask		= 0xf,
894*9e054ec2SFabien DESSENNE 	.cra_type		= &crypto_ablkcipher_type,
895*9e054ec2SFabien DESSENNE 	.cra_module		= THIS_MODULE,
896*9e054ec2SFabien DESSENNE 	.cra_init		= stm32_cryp_cra_init,
897*9e054ec2SFabien DESSENNE 	.cra_ablkcipher = {
898*9e054ec2SFabien DESSENNE 		.min_keysize	= AES_MIN_KEY_SIZE,
899*9e054ec2SFabien DESSENNE 		.max_keysize	= AES_MAX_KEY_SIZE,
900*9e054ec2SFabien DESSENNE 		.setkey		= stm32_cryp_aes_setkey,
901*9e054ec2SFabien DESSENNE 		.encrypt	= stm32_cryp_aes_ecb_encrypt,
902*9e054ec2SFabien DESSENNE 		.decrypt	= stm32_cryp_aes_ecb_decrypt,
903*9e054ec2SFabien DESSENNE 	}
904*9e054ec2SFabien DESSENNE },
905*9e054ec2SFabien DESSENNE {
906*9e054ec2SFabien DESSENNE 	.cra_name		= "cbc(aes)",
907*9e054ec2SFabien DESSENNE 	.cra_driver_name	= "stm32-cbc-aes",
908*9e054ec2SFabien DESSENNE 	.cra_priority		= 200,
909*9e054ec2SFabien DESSENNE 	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER |
910*9e054ec2SFabien DESSENNE 				  CRYPTO_ALG_ASYNC,
911*9e054ec2SFabien DESSENNE 	.cra_blocksize		= AES_BLOCK_SIZE,
912*9e054ec2SFabien DESSENNE 	.cra_ctxsize		= sizeof(struct stm32_cryp_ctx),
913*9e054ec2SFabien DESSENNE 	.cra_alignmask		= 0xf,
914*9e054ec2SFabien DESSENNE 	.cra_type		= &crypto_ablkcipher_type,
915*9e054ec2SFabien DESSENNE 	.cra_module		= THIS_MODULE,
916*9e054ec2SFabien DESSENNE 	.cra_init		= stm32_cryp_cra_init,
917*9e054ec2SFabien DESSENNE 	.cra_ablkcipher = {
918*9e054ec2SFabien DESSENNE 		.min_keysize	= AES_MIN_KEY_SIZE,
919*9e054ec2SFabien DESSENNE 		.max_keysize	= AES_MAX_KEY_SIZE,
920*9e054ec2SFabien DESSENNE 		.ivsize		= AES_BLOCK_SIZE,
921*9e054ec2SFabien DESSENNE 		.setkey		= stm32_cryp_aes_setkey,
922*9e054ec2SFabien DESSENNE 		.encrypt	= stm32_cryp_aes_cbc_encrypt,
923*9e054ec2SFabien DESSENNE 		.decrypt	= stm32_cryp_aes_cbc_decrypt,
924*9e054ec2SFabien DESSENNE 	}
925*9e054ec2SFabien DESSENNE },
926*9e054ec2SFabien DESSENNE {
927*9e054ec2SFabien DESSENNE 	.cra_name		= "ctr(aes)",
928*9e054ec2SFabien DESSENNE 	.cra_driver_name	= "stm32-ctr-aes",
929*9e054ec2SFabien DESSENNE 	.cra_priority		= 200,
930*9e054ec2SFabien DESSENNE 	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER |
931*9e054ec2SFabien DESSENNE 				  CRYPTO_ALG_ASYNC,
932*9e054ec2SFabien DESSENNE 	.cra_blocksize		= 1,
933*9e054ec2SFabien DESSENNE 	.cra_ctxsize		= sizeof(struct stm32_cryp_ctx),
934*9e054ec2SFabien DESSENNE 	.cra_alignmask		= 0xf,
935*9e054ec2SFabien DESSENNE 	.cra_type		= &crypto_ablkcipher_type,
936*9e054ec2SFabien DESSENNE 	.cra_module		= THIS_MODULE,
937*9e054ec2SFabien DESSENNE 	.cra_init		= stm32_cryp_cra_init,
938*9e054ec2SFabien DESSENNE 	.cra_ablkcipher = {
939*9e054ec2SFabien DESSENNE 		.min_keysize	= AES_MIN_KEY_SIZE,
940*9e054ec2SFabien DESSENNE 		.max_keysize	= AES_MAX_KEY_SIZE,
941*9e054ec2SFabien DESSENNE 		.ivsize		= AES_BLOCK_SIZE,
942*9e054ec2SFabien DESSENNE 		.setkey		= stm32_cryp_aes_setkey,
943*9e054ec2SFabien DESSENNE 		.encrypt	= stm32_cryp_aes_ctr_encrypt,
944*9e054ec2SFabien DESSENNE 		.decrypt	= stm32_cryp_aes_ctr_decrypt,
945*9e054ec2SFabien DESSENNE 	}
946*9e054ec2SFabien DESSENNE },
947*9e054ec2SFabien DESSENNE {
948*9e054ec2SFabien DESSENNE 	.cra_name		= "ecb(des)",
949*9e054ec2SFabien DESSENNE 	.cra_driver_name	= "stm32-ecb-des",
950*9e054ec2SFabien DESSENNE 	.cra_priority		= 200,
951*9e054ec2SFabien DESSENNE 	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER |
952*9e054ec2SFabien DESSENNE 				  CRYPTO_ALG_ASYNC,
953*9e054ec2SFabien DESSENNE 	.cra_blocksize		= DES_BLOCK_SIZE,
954*9e054ec2SFabien DESSENNE 	.cra_ctxsize		= sizeof(struct stm32_cryp_ctx),
955*9e054ec2SFabien DESSENNE 	.cra_alignmask		= 0xf,
956*9e054ec2SFabien DESSENNE 	.cra_type		= &crypto_ablkcipher_type,
957*9e054ec2SFabien DESSENNE 	.cra_module		= THIS_MODULE,
958*9e054ec2SFabien DESSENNE 	.cra_init		= stm32_cryp_cra_init,
959*9e054ec2SFabien DESSENNE 	.cra_ablkcipher = {
960*9e054ec2SFabien DESSENNE 		.min_keysize	= DES_BLOCK_SIZE,
961*9e054ec2SFabien DESSENNE 		.max_keysize	= DES_BLOCK_SIZE,
962*9e054ec2SFabien DESSENNE 		.setkey		= stm32_cryp_des_setkey,
963*9e054ec2SFabien DESSENNE 		.encrypt	= stm32_cryp_des_ecb_encrypt,
964*9e054ec2SFabien DESSENNE 		.decrypt	= stm32_cryp_des_ecb_decrypt,
965*9e054ec2SFabien DESSENNE 	}
966*9e054ec2SFabien DESSENNE },
967*9e054ec2SFabien DESSENNE {
968*9e054ec2SFabien DESSENNE 	.cra_name		= "cbc(des)",
969*9e054ec2SFabien DESSENNE 	.cra_driver_name	= "stm32-cbc-des",
970*9e054ec2SFabien DESSENNE 	.cra_priority		= 200,
971*9e054ec2SFabien DESSENNE 	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER |
972*9e054ec2SFabien DESSENNE 				  CRYPTO_ALG_ASYNC,
973*9e054ec2SFabien DESSENNE 	.cra_blocksize		= DES_BLOCK_SIZE,
974*9e054ec2SFabien DESSENNE 	.cra_ctxsize		= sizeof(struct stm32_cryp_ctx),
975*9e054ec2SFabien DESSENNE 	.cra_alignmask		= 0xf,
976*9e054ec2SFabien DESSENNE 	.cra_type		= &crypto_ablkcipher_type,
977*9e054ec2SFabien DESSENNE 	.cra_module		= THIS_MODULE,
978*9e054ec2SFabien DESSENNE 	.cra_init		= stm32_cryp_cra_init,
979*9e054ec2SFabien DESSENNE 	.cra_ablkcipher = {
980*9e054ec2SFabien DESSENNE 		.min_keysize	= DES_BLOCK_SIZE,
981*9e054ec2SFabien DESSENNE 		.max_keysize	= DES_BLOCK_SIZE,
982*9e054ec2SFabien DESSENNE 		.ivsize		= DES_BLOCK_SIZE,
983*9e054ec2SFabien DESSENNE 		.setkey		= stm32_cryp_des_setkey,
984*9e054ec2SFabien DESSENNE 		.encrypt	= stm32_cryp_des_cbc_encrypt,
985*9e054ec2SFabien DESSENNE 		.decrypt	= stm32_cryp_des_cbc_decrypt,
986*9e054ec2SFabien DESSENNE 	}
987*9e054ec2SFabien DESSENNE },
988*9e054ec2SFabien DESSENNE {
989*9e054ec2SFabien DESSENNE 	.cra_name		= "ecb(des3_ede)",
990*9e054ec2SFabien DESSENNE 	.cra_driver_name	= "stm32-ecb-des3",
991*9e054ec2SFabien DESSENNE 	.cra_priority		= 200,
992*9e054ec2SFabien DESSENNE 	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER |
993*9e054ec2SFabien DESSENNE 				  CRYPTO_ALG_ASYNC,
994*9e054ec2SFabien DESSENNE 	.cra_blocksize		= DES_BLOCK_SIZE,
995*9e054ec2SFabien DESSENNE 	.cra_ctxsize		= sizeof(struct stm32_cryp_ctx),
996*9e054ec2SFabien DESSENNE 	.cra_alignmask		= 0xf,
997*9e054ec2SFabien DESSENNE 	.cra_type		= &crypto_ablkcipher_type,
998*9e054ec2SFabien DESSENNE 	.cra_module		= THIS_MODULE,
999*9e054ec2SFabien DESSENNE 	.cra_init		= stm32_cryp_cra_init,
1000*9e054ec2SFabien DESSENNE 	.cra_ablkcipher = {
1001*9e054ec2SFabien DESSENNE 		.min_keysize	= 3 * DES_BLOCK_SIZE,
1002*9e054ec2SFabien DESSENNE 		.max_keysize	= 3 * DES_BLOCK_SIZE,
1003*9e054ec2SFabien DESSENNE 		.setkey		= stm32_cryp_tdes_setkey,
1004*9e054ec2SFabien DESSENNE 		.encrypt	= stm32_cryp_tdes_ecb_encrypt,
1005*9e054ec2SFabien DESSENNE 		.decrypt	= stm32_cryp_tdes_ecb_decrypt,
1006*9e054ec2SFabien DESSENNE 	}
1007*9e054ec2SFabien DESSENNE },
1008*9e054ec2SFabien DESSENNE {
1009*9e054ec2SFabien DESSENNE 	.cra_name		= "cbc(des3_ede)",
1010*9e054ec2SFabien DESSENNE 	.cra_driver_name	= "stm32-cbc-des3",
1011*9e054ec2SFabien DESSENNE 	.cra_priority		= 200,
1012*9e054ec2SFabien DESSENNE 	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER |
1013*9e054ec2SFabien DESSENNE 				  CRYPTO_ALG_ASYNC,
1014*9e054ec2SFabien DESSENNE 	.cra_blocksize		= DES_BLOCK_SIZE,
1015*9e054ec2SFabien DESSENNE 	.cra_ctxsize		= sizeof(struct stm32_cryp_ctx),
1016*9e054ec2SFabien DESSENNE 	.cra_alignmask		= 0xf,
1017*9e054ec2SFabien DESSENNE 	.cra_type		= &crypto_ablkcipher_type,
1018*9e054ec2SFabien DESSENNE 	.cra_module		= THIS_MODULE,
1019*9e054ec2SFabien DESSENNE 	.cra_init		= stm32_cryp_cra_init,
1020*9e054ec2SFabien DESSENNE 	.cra_ablkcipher = {
1021*9e054ec2SFabien DESSENNE 		.min_keysize	= 3 * DES_BLOCK_SIZE,
1022*9e054ec2SFabien DESSENNE 		.max_keysize	= 3 * DES_BLOCK_SIZE,
1023*9e054ec2SFabien DESSENNE 		.ivsize		= DES_BLOCK_SIZE,
1024*9e054ec2SFabien DESSENNE 		.setkey		= stm32_cryp_tdes_setkey,
1025*9e054ec2SFabien DESSENNE 		.encrypt	= stm32_cryp_tdes_cbc_encrypt,
1026*9e054ec2SFabien DESSENNE 		.decrypt	= stm32_cryp_tdes_cbc_decrypt,
1027*9e054ec2SFabien DESSENNE 	}
1028*9e054ec2SFabien DESSENNE },
1029*9e054ec2SFabien DESSENNE };
1030*9e054ec2SFabien DESSENNE 
1031*9e054ec2SFabien DESSENNE static const struct of_device_id stm32_dt_ids[] = {
1032*9e054ec2SFabien DESSENNE 	{ .compatible = "st,stm32f756-cryp", },
1033*9e054ec2SFabien DESSENNE 	{},
1034*9e054ec2SFabien DESSENNE };
1035*9e054ec2SFabien DESSENNE MODULE_DEVICE_TABLE(of, sti_dt_ids);
1036*9e054ec2SFabien DESSENNE 
1037*9e054ec2SFabien DESSENNE static int stm32_cryp_probe(struct platform_device *pdev)
1038*9e054ec2SFabien DESSENNE {
1039*9e054ec2SFabien DESSENNE 	struct device *dev = &pdev->dev;
1040*9e054ec2SFabien DESSENNE 	struct stm32_cryp *cryp;
1041*9e054ec2SFabien DESSENNE 	struct resource *res;
1042*9e054ec2SFabien DESSENNE 	struct reset_control *rst;
1043*9e054ec2SFabien DESSENNE 	int irq, ret;
1044*9e054ec2SFabien DESSENNE 
1045*9e054ec2SFabien DESSENNE 	cryp = devm_kzalloc(dev, sizeof(*cryp), GFP_KERNEL);
1046*9e054ec2SFabien DESSENNE 	if (!cryp)
1047*9e054ec2SFabien DESSENNE 		return -ENOMEM;
1048*9e054ec2SFabien DESSENNE 
1049*9e054ec2SFabien DESSENNE 	cryp->dev = dev;
1050*9e054ec2SFabien DESSENNE 
1051*9e054ec2SFabien DESSENNE 	mutex_init(&cryp->lock);
1052*9e054ec2SFabien DESSENNE 
1053*9e054ec2SFabien DESSENNE 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1054*9e054ec2SFabien DESSENNE 	cryp->regs = devm_ioremap_resource(dev, res);
1055*9e054ec2SFabien DESSENNE 	if (IS_ERR(cryp->regs)) {
1056*9e054ec2SFabien DESSENNE 		dev_err(dev, "Cannot map CRYP IO\n");
1057*9e054ec2SFabien DESSENNE 		return PTR_ERR(cryp->regs);
1058*9e054ec2SFabien DESSENNE 	}
1059*9e054ec2SFabien DESSENNE 
1060*9e054ec2SFabien DESSENNE 	irq = platform_get_irq(pdev, 0);
1061*9e054ec2SFabien DESSENNE 	if (irq < 0) {
1062*9e054ec2SFabien DESSENNE 		dev_err(dev, "Cannot get IRQ resource\n");
1063*9e054ec2SFabien DESSENNE 		return irq;
1064*9e054ec2SFabien DESSENNE 	}
1065*9e054ec2SFabien DESSENNE 
1066*9e054ec2SFabien DESSENNE 	ret = devm_request_threaded_irq(dev, irq, stm32_cryp_irq,
1067*9e054ec2SFabien DESSENNE 					stm32_cryp_irq_thread, IRQF_ONESHOT,
1068*9e054ec2SFabien DESSENNE 					dev_name(dev), cryp);
1069*9e054ec2SFabien DESSENNE 	if (ret) {
1070*9e054ec2SFabien DESSENNE 		dev_err(dev, "Cannot grab IRQ\n");
1071*9e054ec2SFabien DESSENNE 		return ret;
1072*9e054ec2SFabien DESSENNE 	}
1073*9e054ec2SFabien DESSENNE 
1074*9e054ec2SFabien DESSENNE 	cryp->clk = devm_clk_get(dev, NULL);
1075*9e054ec2SFabien DESSENNE 	if (IS_ERR(cryp->clk)) {
1076*9e054ec2SFabien DESSENNE 		dev_err(dev, "Could not get clock\n");
1077*9e054ec2SFabien DESSENNE 		return PTR_ERR(cryp->clk);
1078*9e054ec2SFabien DESSENNE 	}
1079*9e054ec2SFabien DESSENNE 
1080*9e054ec2SFabien DESSENNE 	ret = clk_prepare_enable(cryp->clk);
1081*9e054ec2SFabien DESSENNE 	if (ret) {
1082*9e054ec2SFabien DESSENNE 		dev_err(cryp->dev, "Failed to enable clock\n");
1083*9e054ec2SFabien DESSENNE 		return ret;
1084*9e054ec2SFabien DESSENNE 	}
1085*9e054ec2SFabien DESSENNE 
1086*9e054ec2SFabien DESSENNE 	rst = devm_reset_control_get(dev, NULL);
1087*9e054ec2SFabien DESSENNE 	if (!IS_ERR(rst)) {
1088*9e054ec2SFabien DESSENNE 		reset_control_assert(rst);
1089*9e054ec2SFabien DESSENNE 		udelay(2);
1090*9e054ec2SFabien DESSENNE 		reset_control_deassert(rst);
1091*9e054ec2SFabien DESSENNE 	}
1092*9e054ec2SFabien DESSENNE 
1093*9e054ec2SFabien DESSENNE 	platform_set_drvdata(pdev, cryp);
1094*9e054ec2SFabien DESSENNE 
1095*9e054ec2SFabien DESSENNE 	spin_lock(&cryp_list.lock);
1096*9e054ec2SFabien DESSENNE 	list_add(&cryp->list, &cryp_list.dev_list);
1097*9e054ec2SFabien DESSENNE 	spin_unlock(&cryp_list.lock);
1098*9e054ec2SFabien DESSENNE 
1099*9e054ec2SFabien DESSENNE 	/* Initialize crypto engine */
1100*9e054ec2SFabien DESSENNE 	cryp->engine = crypto_engine_alloc_init(dev, 1);
1101*9e054ec2SFabien DESSENNE 	if (!cryp->engine) {
1102*9e054ec2SFabien DESSENNE 		dev_err(dev, "Could not init crypto engine\n");
1103*9e054ec2SFabien DESSENNE 		ret = -ENOMEM;
1104*9e054ec2SFabien DESSENNE 		goto err_engine1;
1105*9e054ec2SFabien DESSENNE 	}
1106*9e054ec2SFabien DESSENNE 
1107*9e054ec2SFabien DESSENNE 	cryp->engine->prepare_cipher_request = stm32_cryp_prepare_cipher_req;
1108*9e054ec2SFabien DESSENNE 	cryp->engine->cipher_one_request = stm32_cryp_cipher_one_req;
1109*9e054ec2SFabien DESSENNE 
1110*9e054ec2SFabien DESSENNE 	ret = crypto_engine_start(cryp->engine);
1111*9e054ec2SFabien DESSENNE 	if (ret) {
1112*9e054ec2SFabien DESSENNE 		dev_err(dev, "Could not start crypto engine\n");
1113*9e054ec2SFabien DESSENNE 		goto err_engine2;
1114*9e054ec2SFabien DESSENNE 	}
1115*9e054ec2SFabien DESSENNE 
1116*9e054ec2SFabien DESSENNE 	ret = crypto_register_algs(crypto_algs, ARRAY_SIZE(crypto_algs));
1117*9e054ec2SFabien DESSENNE 	if (ret) {
1118*9e054ec2SFabien DESSENNE 		dev_err(dev, "Could not register algs\n");
1119*9e054ec2SFabien DESSENNE 		goto err_algs;
1120*9e054ec2SFabien DESSENNE 	}
1121*9e054ec2SFabien DESSENNE 
1122*9e054ec2SFabien DESSENNE 	dev_info(dev, "Initialized\n");
1123*9e054ec2SFabien DESSENNE 
1124*9e054ec2SFabien DESSENNE 	return 0;
1125*9e054ec2SFabien DESSENNE 
1126*9e054ec2SFabien DESSENNE err_algs:
1127*9e054ec2SFabien DESSENNE err_engine2:
1128*9e054ec2SFabien DESSENNE 	crypto_engine_exit(cryp->engine);
1129*9e054ec2SFabien DESSENNE err_engine1:
1130*9e054ec2SFabien DESSENNE 	spin_lock(&cryp_list.lock);
1131*9e054ec2SFabien DESSENNE 	list_del(&cryp->list);
1132*9e054ec2SFabien DESSENNE 	spin_unlock(&cryp_list.lock);
1133*9e054ec2SFabien DESSENNE 
1134*9e054ec2SFabien DESSENNE 	clk_disable_unprepare(cryp->clk);
1135*9e054ec2SFabien DESSENNE 
1136*9e054ec2SFabien DESSENNE 	return ret;
1137*9e054ec2SFabien DESSENNE }
1138*9e054ec2SFabien DESSENNE 
1139*9e054ec2SFabien DESSENNE static int stm32_cryp_remove(struct platform_device *pdev)
1140*9e054ec2SFabien DESSENNE {
1141*9e054ec2SFabien DESSENNE 	struct stm32_cryp *cryp = platform_get_drvdata(pdev);
1142*9e054ec2SFabien DESSENNE 
1143*9e054ec2SFabien DESSENNE 	if (!cryp)
1144*9e054ec2SFabien DESSENNE 		return -ENODEV;
1145*9e054ec2SFabien DESSENNE 
1146*9e054ec2SFabien DESSENNE 	crypto_unregister_algs(crypto_algs, ARRAY_SIZE(crypto_algs));
1147*9e054ec2SFabien DESSENNE 
1148*9e054ec2SFabien DESSENNE 	crypto_engine_exit(cryp->engine);
1149*9e054ec2SFabien DESSENNE 
1150*9e054ec2SFabien DESSENNE 	spin_lock(&cryp_list.lock);
1151*9e054ec2SFabien DESSENNE 	list_del(&cryp->list);
1152*9e054ec2SFabien DESSENNE 	spin_unlock(&cryp_list.lock);
1153*9e054ec2SFabien DESSENNE 
1154*9e054ec2SFabien DESSENNE 	clk_disable_unprepare(cryp->clk);
1155*9e054ec2SFabien DESSENNE 
1156*9e054ec2SFabien DESSENNE 	return 0;
1157*9e054ec2SFabien DESSENNE }
1158*9e054ec2SFabien DESSENNE 
1159*9e054ec2SFabien DESSENNE static struct platform_driver stm32_cryp_driver = {
1160*9e054ec2SFabien DESSENNE 	.probe  = stm32_cryp_probe,
1161*9e054ec2SFabien DESSENNE 	.remove = stm32_cryp_remove,
1162*9e054ec2SFabien DESSENNE 	.driver = {
1163*9e054ec2SFabien DESSENNE 		.name           = DRIVER_NAME,
1164*9e054ec2SFabien DESSENNE 		.of_match_table = stm32_dt_ids,
1165*9e054ec2SFabien DESSENNE 	},
1166*9e054ec2SFabien DESSENNE };
1167*9e054ec2SFabien DESSENNE 
1168*9e054ec2SFabien DESSENNE module_platform_driver(stm32_cryp_driver);
1169*9e054ec2SFabien DESSENNE 
1170*9e054ec2SFabien DESSENNE MODULE_AUTHOR("Fabien Dessenne <fabien.dessenne@st.com>");
1171*9e054ec2SFabien DESSENNE MODULE_DESCRIPTION("STMicrolectronics STM32 CRYP hardware driver");
1172*9e054ec2SFabien DESSENNE MODULE_LICENSE("GPL");
1173