1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * sun4i-ss-cipher.c - hardware cryptographic accelerator for Allwinner A20 SoC
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2013-2015 Corentin LABBE <clabbe.montjoie@gmail.com>
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * This file add support for AES cipher with 128,192,256 bits
8*4882a593Smuzhiyun * keysize in CBC and ECB mode.
9*4882a593Smuzhiyun * Add support also for DES and 3DES in CBC and ECB mode.
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun * You could find the datasheet in Documentation/arm/sunxi.rst
12*4882a593Smuzhiyun */
13*4882a593Smuzhiyun #include "sun4i-ss.h"
14*4882a593Smuzhiyun
sun4i_ss_opti_poll(struct skcipher_request * areq)15*4882a593Smuzhiyun static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
16*4882a593Smuzhiyun {
17*4882a593Smuzhiyun struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
18*4882a593Smuzhiyun struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);
19*4882a593Smuzhiyun struct sun4i_ss_ctx *ss = op->ss;
20*4882a593Smuzhiyun unsigned int ivsize = crypto_skcipher_ivsize(tfm);
21*4882a593Smuzhiyun struct sun4i_cipher_req_ctx *ctx = skcipher_request_ctx(areq);
22*4882a593Smuzhiyun u32 mode = ctx->mode;
23*4882a593Smuzhiyun void *backup_iv = NULL;
24*4882a593Smuzhiyun /* when activating SS, the default FIFO space is SS_RX_DEFAULT(32) */
25*4882a593Smuzhiyun u32 rx_cnt = SS_RX_DEFAULT;
26*4882a593Smuzhiyun u32 tx_cnt = 0;
27*4882a593Smuzhiyun u32 spaces;
28*4882a593Smuzhiyun u32 v;
29*4882a593Smuzhiyun int err = 0;
30*4882a593Smuzhiyun unsigned int i;
31*4882a593Smuzhiyun unsigned int ileft = areq->cryptlen;
32*4882a593Smuzhiyun unsigned int oleft = areq->cryptlen;
33*4882a593Smuzhiyun unsigned int todo;
34*4882a593Smuzhiyun unsigned long pi = 0, po = 0; /* progress for in and out */
35*4882a593Smuzhiyun bool miter_err;
36*4882a593Smuzhiyun struct sg_mapping_iter mi, mo;
37*4882a593Smuzhiyun unsigned int oi, oo; /* offset for in and out */
38*4882a593Smuzhiyun unsigned long flags;
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun if (!areq->cryptlen)
41*4882a593Smuzhiyun return 0;
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun if (!areq->src || !areq->dst) {
44*4882a593Smuzhiyun dev_err_ratelimited(ss->dev, "ERROR: Some SGs are NULL\n");
45*4882a593Smuzhiyun return -EINVAL;
46*4882a593Smuzhiyun }
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun if (areq->iv && ivsize > 0 && mode & SS_DECRYPTION) {
49*4882a593Smuzhiyun backup_iv = kzalloc(ivsize, GFP_KERNEL);
50*4882a593Smuzhiyun if (!backup_iv)
51*4882a593Smuzhiyun return -ENOMEM;
52*4882a593Smuzhiyun scatterwalk_map_and_copy(backup_iv, areq->src, areq->cryptlen - ivsize, ivsize, 0);
53*4882a593Smuzhiyun }
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun spin_lock_irqsave(&ss->slock, flags);
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun for (i = 0; i < op->keylen / 4; i++)
58*4882a593Smuzhiyun writesl(ss->base + SS_KEY0 + i * 4, &op->key[i], 1);
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun if (areq->iv) {
61*4882a593Smuzhiyun for (i = 0; i < 4 && i < ivsize / 4; i++) {
62*4882a593Smuzhiyun v = *(u32 *)(areq->iv + i * 4);
63*4882a593Smuzhiyun writesl(ss->base + SS_IV0 + i * 4, &v, 1);
64*4882a593Smuzhiyun }
65*4882a593Smuzhiyun }
66*4882a593Smuzhiyun writel(mode, ss->base + SS_CTL);
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun ileft = areq->cryptlen / 4;
70*4882a593Smuzhiyun oleft = areq->cryptlen / 4;
71*4882a593Smuzhiyun oi = 0;
72*4882a593Smuzhiyun oo = 0;
73*4882a593Smuzhiyun do {
74*4882a593Smuzhiyun if (ileft) {
75*4882a593Smuzhiyun sg_miter_start(&mi, areq->src, sg_nents(areq->src),
76*4882a593Smuzhiyun SG_MITER_FROM_SG | SG_MITER_ATOMIC);
77*4882a593Smuzhiyun if (pi)
78*4882a593Smuzhiyun sg_miter_skip(&mi, pi);
79*4882a593Smuzhiyun miter_err = sg_miter_next(&mi);
80*4882a593Smuzhiyun if (!miter_err || !mi.addr) {
81*4882a593Smuzhiyun dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n");
82*4882a593Smuzhiyun err = -EINVAL;
83*4882a593Smuzhiyun goto release_ss;
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun todo = min(rx_cnt, ileft);
86*4882a593Smuzhiyun todo = min_t(size_t, todo, (mi.length - oi) / 4);
87*4882a593Smuzhiyun if (todo) {
88*4882a593Smuzhiyun ileft -= todo;
89*4882a593Smuzhiyun writesl(ss->base + SS_RXFIFO, mi.addr + oi, todo);
90*4882a593Smuzhiyun oi += todo * 4;
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun if (oi == mi.length) {
93*4882a593Smuzhiyun pi += mi.length;
94*4882a593Smuzhiyun oi = 0;
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun sg_miter_stop(&mi);
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun spaces = readl(ss->base + SS_FCSR);
100*4882a593Smuzhiyun rx_cnt = SS_RXFIFO_SPACES(spaces);
101*4882a593Smuzhiyun tx_cnt = SS_TXFIFO_SPACES(spaces);
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun sg_miter_start(&mo, areq->dst, sg_nents(areq->dst),
104*4882a593Smuzhiyun SG_MITER_TO_SG | SG_MITER_ATOMIC);
105*4882a593Smuzhiyun if (po)
106*4882a593Smuzhiyun sg_miter_skip(&mo, po);
107*4882a593Smuzhiyun miter_err = sg_miter_next(&mo);
108*4882a593Smuzhiyun if (!miter_err || !mo.addr) {
109*4882a593Smuzhiyun dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n");
110*4882a593Smuzhiyun err = -EINVAL;
111*4882a593Smuzhiyun goto release_ss;
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun todo = min(tx_cnt, oleft);
114*4882a593Smuzhiyun todo = min_t(size_t, todo, (mo.length - oo) / 4);
115*4882a593Smuzhiyun if (todo) {
116*4882a593Smuzhiyun oleft -= todo;
117*4882a593Smuzhiyun readsl(ss->base + SS_TXFIFO, mo.addr + oo, todo);
118*4882a593Smuzhiyun oo += todo * 4;
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun if (oo == mo.length) {
121*4882a593Smuzhiyun oo = 0;
122*4882a593Smuzhiyun po += mo.length;
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun sg_miter_stop(&mo);
125*4882a593Smuzhiyun } while (oleft);
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun if (areq->iv) {
128*4882a593Smuzhiyun if (mode & SS_DECRYPTION) {
129*4882a593Smuzhiyun memcpy(areq->iv, backup_iv, ivsize);
130*4882a593Smuzhiyun kfree_sensitive(backup_iv);
131*4882a593Smuzhiyun } else {
132*4882a593Smuzhiyun scatterwalk_map_and_copy(areq->iv, areq->dst, areq->cryptlen - ivsize,
133*4882a593Smuzhiyun ivsize, 0);
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun release_ss:
138*4882a593Smuzhiyun writel(0, ss->base + SS_CTL);
139*4882a593Smuzhiyun spin_unlock_irqrestore(&ss->slock, flags);
140*4882a593Smuzhiyun return err;
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun
sun4i_ss_cipher_poll_fallback(struct skcipher_request * areq)144*4882a593Smuzhiyun static int noinline_for_stack sun4i_ss_cipher_poll_fallback(struct skcipher_request *areq)
145*4882a593Smuzhiyun {
146*4882a593Smuzhiyun struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
147*4882a593Smuzhiyun struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);
148*4882a593Smuzhiyun struct sun4i_cipher_req_ctx *ctx = skcipher_request_ctx(areq);
149*4882a593Smuzhiyun int err;
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun skcipher_request_set_tfm(&ctx->fallback_req, op->fallback_tfm);
152*4882a593Smuzhiyun skcipher_request_set_callback(&ctx->fallback_req, areq->base.flags,
153*4882a593Smuzhiyun areq->base.complete, areq->base.data);
154*4882a593Smuzhiyun skcipher_request_set_crypt(&ctx->fallback_req, areq->src, areq->dst,
155*4882a593Smuzhiyun areq->cryptlen, areq->iv);
156*4882a593Smuzhiyun if (ctx->mode & SS_DECRYPTION)
157*4882a593Smuzhiyun err = crypto_skcipher_decrypt(&ctx->fallback_req);
158*4882a593Smuzhiyun else
159*4882a593Smuzhiyun err = crypto_skcipher_encrypt(&ctx->fallback_req);
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun return err;
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun /* Generic function that support SG with size not multiple of 4 */
sun4i_ss_cipher_poll(struct skcipher_request * areq)165*4882a593Smuzhiyun static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
166*4882a593Smuzhiyun {
167*4882a593Smuzhiyun struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
168*4882a593Smuzhiyun struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);
169*4882a593Smuzhiyun struct sun4i_ss_ctx *ss = op->ss;
170*4882a593Smuzhiyun int no_chunk = 1;
171*4882a593Smuzhiyun struct scatterlist *in_sg = areq->src;
172*4882a593Smuzhiyun struct scatterlist *out_sg = areq->dst;
173*4882a593Smuzhiyun unsigned int ivsize = crypto_skcipher_ivsize(tfm);
174*4882a593Smuzhiyun struct sun4i_cipher_req_ctx *ctx = skcipher_request_ctx(areq);
175*4882a593Smuzhiyun struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
176*4882a593Smuzhiyun struct sun4i_ss_alg_template *algt;
177*4882a593Smuzhiyun u32 mode = ctx->mode;
178*4882a593Smuzhiyun /* when activating SS, the default FIFO space is SS_RX_DEFAULT(32) */
179*4882a593Smuzhiyun u32 rx_cnt = SS_RX_DEFAULT;
180*4882a593Smuzhiyun u32 tx_cnt = 0;
181*4882a593Smuzhiyun u32 v;
182*4882a593Smuzhiyun u32 spaces;
183*4882a593Smuzhiyun int err = 0;
184*4882a593Smuzhiyun unsigned int i;
185*4882a593Smuzhiyun unsigned int ileft = areq->cryptlen;
186*4882a593Smuzhiyun unsigned int oleft = areq->cryptlen;
187*4882a593Smuzhiyun unsigned int todo;
188*4882a593Smuzhiyun void *backup_iv = NULL;
189*4882a593Smuzhiyun struct sg_mapping_iter mi, mo;
190*4882a593Smuzhiyun unsigned long pi = 0, po = 0; /* progress for in and out */
191*4882a593Smuzhiyun bool miter_err;
192*4882a593Smuzhiyun unsigned int oi, oo; /* offset for in and out */
193*4882a593Smuzhiyun unsigned int ob = 0; /* offset in buf */
194*4882a593Smuzhiyun unsigned int obo = 0; /* offset in bufo*/
195*4882a593Smuzhiyun unsigned int obl = 0; /* length of data in bufo */
196*4882a593Smuzhiyun unsigned long flags;
197*4882a593Smuzhiyun bool need_fallback = false;
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun if (!areq->cryptlen)
200*4882a593Smuzhiyun return 0;
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun if (!areq->src || !areq->dst) {
203*4882a593Smuzhiyun dev_err_ratelimited(ss->dev, "ERROR: Some SGs are NULL\n");
204*4882a593Smuzhiyun return -EINVAL;
205*4882a593Smuzhiyun }
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun algt = container_of(alg, struct sun4i_ss_alg_template, alg.crypto);
208*4882a593Smuzhiyun if (areq->cryptlen % algt->alg.crypto.base.cra_blocksize)
209*4882a593Smuzhiyun need_fallback = true;
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun /*
212*4882a593Smuzhiyun * if we have only SGs with size multiple of 4,
213*4882a593Smuzhiyun * we can use the SS optimized function
214*4882a593Smuzhiyun */
215*4882a593Smuzhiyun while (in_sg && no_chunk == 1) {
216*4882a593Smuzhiyun if ((in_sg->length | in_sg->offset) & 3u)
217*4882a593Smuzhiyun no_chunk = 0;
218*4882a593Smuzhiyun in_sg = sg_next(in_sg);
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun while (out_sg && no_chunk == 1) {
221*4882a593Smuzhiyun if ((out_sg->length | out_sg->offset) & 3u)
222*4882a593Smuzhiyun no_chunk = 0;
223*4882a593Smuzhiyun out_sg = sg_next(out_sg);
224*4882a593Smuzhiyun }
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun if (no_chunk == 1 && !need_fallback)
227*4882a593Smuzhiyun return sun4i_ss_opti_poll(areq);
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun if (need_fallback)
230*4882a593Smuzhiyun return sun4i_ss_cipher_poll_fallback(areq);
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun if (areq->iv && ivsize > 0 && mode & SS_DECRYPTION) {
233*4882a593Smuzhiyun backup_iv = kzalloc(ivsize, GFP_KERNEL);
234*4882a593Smuzhiyun if (!backup_iv)
235*4882a593Smuzhiyun return -ENOMEM;
236*4882a593Smuzhiyun scatterwalk_map_and_copy(backup_iv, areq->src, areq->cryptlen - ivsize, ivsize, 0);
237*4882a593Smuzhiyun }
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun spin_lock_irqsave(&ss->slock, flags);
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun for (i = 0; i < op->keylen / 4; i++)
242*4882a593Smuzhiyun writesl(ss->base + SS_KEY0 + i * 4, &op->key[i], 1);
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun if (areq->iv) {
245*4882a593Smuzhiyun for (i = 0; i < 4 && i < ivsize / 4; i++) {
246*4882a593Smuzhiyun v = *(u32 *)(areq->iv + i * 4);
247*4882a593Smuzhiyun writesl(ss->base + SS_IV0 + i * 4, &v, 1);
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun }
250*4882a593Smuzhiyun writel(mode, ss->base + SS_CTL);
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun ileft = areq->cryptlen;
253*4882a593Smuzhiyun oleft = areq->cryptlen;
254*4882a593Smuzhiyun oi = 0;
255*4882a593Smuzhiyun oo = 0;
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun while (oleft) {
258*4882a593Smuzhiyun if (ileft) {
259*4882a593Smuzhiyun sg_miter_start(&mi, areq->src, sg_nents(areq->src),
260*4882a593Smuzhiyun SG_MITER_FROM_SG | SG_MITER_ATOMIC);
261*4882a593Smuzhiyun if (pi)
262*4882a593Smuzhiyun sg_miter_skip(&mi, pi);
263*4882a593Smuzhiyun miter_err = sg_miter_next(&mi);
264*4882a593Smuzhiyun if (!miter_err || !mi.addr) {
265*4882a593Smuzhiyun dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n");
266*4882a593Smuzhiyun err = -EINVAL;
267*4882a593Smuzhiyun goto release_ss;
268*4882a593Smuzhiyun }
269*4882a593Smuzhiyun /*
270*4882a593Smuzhiyun * todo is the number of consecutive 4byte word that we
271*4882a593Smuzhiyun * can read from current SG
272*4882a593Smuzhiyun */
273*4882a593Smuzhiyun todo = min(rx_cnt, ileft / 4);
274*4882a593Smuzhiyun todo = min_t(size_t, todo, (mi.length - oi) / 4);
275*4882a593Smuzhiyun if (todo && !ob) {
276*4882a593Smuzhiyun writesl(ss->base + SS_RXFIFO, mi.addr + oi,
277*4882a593Smuzhiyun todo);
278*4882a593Smuzhiyun ileft -= todo * 4;
279*4882a593Smuzhiyun oi += todo * 4;
280*4882a593Smuzhiyun } else {
281*4882a593Smuzhiyun /*
282*4882a593Smuzhiyun * not enough consecutive bytes, so we need to
283*4882a593Smuzhiyun * linearize in buf. todo is in bytes
284*4882a593Smuzhiyun * After that copy, if we have a multiple of 4
285*4882a593Smuzhiyun * we need to be able to write all buf in one
286*4882a593Smuzhiyun * pass, so it is why we min() with rx_cnt
287*4882a593Smuzhiyun */
288*4882a593Smuzhiyun todo = min(rx_cnt * 4 - ob, ileft);
289*4882a593Smuzhiyun todo = min_t(size_t, todo, mi.length - oi);
290*4882a593Smuzhiyun memcpy(ss->buf + ob, mi.addr + oi, todo);
291*4882a593Smuzhiyun ileft -= todo;
292*4882a593Smuzhiyun oi += todo;
293*4882a593Smuzhiyun ob += todo;
294*4882a593Smuzhiyun if (!(ob % 4)) {
295*4882a593Smuzhiyun writesl(ss->base + SS_RXFIFO, ss->buf,
296*4882a593Smuzhiyun ob / 4);
297*4882a593Smuzhiyun ob = 0;
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun if (oi == mi.length) {
301*4882a593Smuzhiyun pi += mi.length;
302*4882a593Smuzhiyun oi = 0;
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun sg_miter_stop(&mi);
305*4882a593Smuzhiyun }
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun spaces = readl(ss->base + SS_FCSR);
308*4882a593Smuzhiyun rx_cnt = SS_RXFIFO_SPACES(spaces);
309*4882a593Smuzhiyun tx_cnt = SS_TXFIFO_SPACES(spaces);
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun if (!tx_cnt)
312*4882a593Smuzhiyun continue;
313*4882a593Smuzhiyun sg_miter_start(&mo, areq->dst, sg_nents(areq->dst),
314*4882a593Smuzhiyun SG_MITER_TO_SG | SG_MITER_ATOMIC);
315*4882a593Smuzhiyun if (po)
316*4882a593Smuzhiyun sg_miter_skip(&mo, po);
317*4882a593Smuzhiyun miter_err = sg_miter_next(&mo);
318*4882a593Smuzhiyun if (!miter_err || !mo.addr) {
319*4882a593Smuzhiyun dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n");
320*4882a593Smuzhiyun err = -EINVAL;
321*4882a593Smuzhiyun goto release_ss;
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun /* todo in 4bytes word */
324*4882a593Smuzhiyun todo = min(tx_cnt, oleft / 4);
325*4882a593Smuzhiyun todo = min_t(size_t, todo, (mo.length - oo) / 4);
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun if (todo) {
328*4882a593Smuzhiyun readsl(ss->base + SS_TXFIFO, mo.addr + oo, todo);
329*4882a593Smuzhiyun oleft -= todo * 4;
330*4882a593Smuzhiyun oo += todo * 4;
331*4882a593Smuzhiyun if (oo == mo.length) {
332*4882a593Smuzhiyun po += mo.length;
333*4882a593Smuzhiyun oo = 0;
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun } else {
336*4882a593Smuzhiyun /*
337*4882a593Smuzhiyun * read obl bytes in bufo, we read at maximum for
338*4882a593Smuzhiyun * emptying the device
339*4882a593Smuzhiyun */
340*4882a593Smuzhiyun readsl(ss->base + SS_TXFIFO, ss->bufo, tx_cnt);
341*4882a593Smuzhiyun obl = tx_cnt * 4;
342*4882a593Smuzhiyun obo = 0;
343*4882a593Smuzhiyun do {
344*4882a593Smuzhiyun /*
345*4882a593Smuzhiyun * how many bytes we can copy ?
346*4882a593Smuzhiyun * no more than remaining SG size
347*4882a593Smuzhiyun * no more than remaining buffer
348*4882a593Smuzhiyun * no need to test against oleft
349*4882a593Smuzhiyun */
350*4882a593Smuzhiyun todo = min_t(size_t,
351*4882a593Smuzhiyun mo.length - oo, obl - obo);
352*4882a593Smuzhiyun memcpy(mo.addr + oo, ss->bufo + obo, todo);
353*4882a593Smuzhiyun oleft -= todo;
354*4882a593Smuzhiyun obo += todo;
355*4882a593Smuzhiyun oo += todo;
356*4882a593Smuzhiyun if (oo == mo.length) {
357*4882a593Smuzhiyun po += mo.length;
358*4882a593Smuzhiyun sg_miter_next(&mo);
359*4882a593Smuzhiyun oo = 0;
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun } while (obo < obl);
362*4882a593Smuzhiyun /* bufo must be fully used here */
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun sg_miter_stop(&mo);
365*4882a593Smuzhiyun }
366*4882a593Smuzhiyun if (areq->iv) {
367*4882a593Smuzhiyun if (mode & SS_DECRYPTION) {
368*4882a593Smuzhiyun memcpy(areq->iv, backup_iv, ivsize);
369*4882a593Smuzhiyun kfree_sensitive(backup_iv);
370*4882a593Smuzhiyun } else {
371*4882a593Smuzhiyun scatterwalk_map_and_copy(areq->iv, areq->dst, areq->cryptlen - ivsize,
372*4882a593Smuzhiyun ivsize, 0);
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun }
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun release_ss:
377*4882a593Smuzhiyun writel(0, ss->base + SS_CTL);
378*4882a593Smuzhiyun spin_unlock_irqrestore(&ss->slock, flags);
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun return err;
381*4882a593Smuzhiyun }
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun /* CBC AES */
sun4i_ss_cbc_aes_encrypt(struct skcipher_request * areq)384*4882a593Smuzhiyun int sun4i_ss_cbc_aes_encrypt(struct skcipher_request *areq)
385*4882a593Smuzhiyun {
386*4882a593Smuzhiyun struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
387*4882a593Smuzhiyun struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);
388*4882a593Smuzhiyun struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);
389*4882a593Smuzhiyun
390*4882a593Smuzhiyun rctx->mode = SS_OP_AES | SS_CBC | SS_ENABLED | SS_ENCRYPTION |
391*4882a593Smuzhiyun op->keymode;
392*4882a593Smuzhiyun return sun4i_ss_cipher_poll(areq);
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun
sun4i_ss_cbc_aes_decrypt(struct skcipher_request * areq)395*4882a593Smuzhiyun int sun4i_ss_cbc_aes_decrypt(struct skcipher_request *areq)
396*4882a593Smuzhiyun {
397*4882a593Smuzhiyun struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
398*4882a593Smuzhiyun struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);
399*4882a593Smuzhiyun struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun rctx->mode = SS_OP_AES | SS_CBC | SS_ENABLED | SS_DECRYPTION |
402*4882a593Smuzhiyun op->keymode;
403*4882a593Smuzhiyun return sun4i_ss_cipher_poll(areq);
404*4882a593Smuzhiyun }
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun /* ECB AES */
sun4i_ss_ecb_aes_encrypt(struct skcipher_request * areq)407*4882a593Smuzhiyun int sun4i_ss_ecb_aes_encrypt(struct skcipher_request *areq)
408*4882a593Smuzhiyun {
409*4882a593Smuzhiyun struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
410*4882a593Smuzhiyun struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);
411*4882a593Smuzhiyun struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);
412*4882a593Smuzhiyun
413*4882a593Smuzhiyun rctx->mode = SS_OP_AES | SS_ECB | SS_ENABLED | SS_ENCRYPTION |
414*4882a593Smuzhiyun op->keymode;
415*4882a593Smuzhiyun return sun4i_ss_cipher_poll(areq);
416*4882a593Smuzhiyun }
417*4882a593Smuzhiyun
sun4i_ss_ecb_aes_decrypt(struct skcipher_request * areq)418*4882a593Smuzhiyun int sun4i_ss_ecb_aes_decrypt(struct skcipher_request *areq)
419*4882a593Smuzhiyun {
420*4882a593Smuzhiyun struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
421*4882a593Smuzhiyun struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);
422*4882a593Smuzhiyun struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun rctx->mode = SS_OP_AES | SS_ECB | SS_ENABLED | SS_DECRYPTION |
425*4882a593Smuzhiyun op->keymode;
426*4882a593Smuzhiyun return sun4i_ss_cipher_poll(areq);
427*4882a593Smuzhiyun }
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun /* CBC DES */
sun4i_ss_cbc_des_encrypt(struct skcipher_request * areq)430*4882a593Smuzhiyun int sun4i_ss_cbc_des_encrypt(struct skcipher_request *areq)
431*4882a593Smuzhiyun {
432*4882a593Smuzhiyun struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
433*4882a593Smuzhiyun struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);
434*4882a593Smuzhiyun struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun rctx->mode = SS_OP_DES | SS_CBC | SS_ENABLED | SS_ENCRYPTION |
437*4882a593Smuzhiyun op->keymode;
438*4882a593Smuzhiyun return sun4i_ss_cipher_poll(areq);
439*4882a593Smuzhiyun }
440*4882a593Smuzhiyun
sun4i_ss_cbc_des_decrypt(struct skcipher_request * areq)441*4882a593Smuzhiyun int sun4i_ss_cbc_des_decrypt(struct skcipher_request *areq)
442*4882a593Smuzhiyun {
443*4882a593Smuzhiyun struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
444*4882a593Smuzhiyun struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);
445*4882a593Smuzhiyun struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun rctx->mode = SS_OP_DES | SS_CBC | SS_ENABLED | SS_DECRYPTION |
448*4882a593Smuzhiyun op->keymode;
449*4882a593Smuzhiyun return sun4i_ss_cipher_poll(areq);
450*4882a593Smuzhiyun }
451*4882a593Smuzhiyun
452*4882a593Smuzhiyun /* ECB DES */
sun4i_ss_ecb_des_encrypt(struct skcipher_request * areq)453*4882a593Smuzhiyun int sun4i_ss_ecb_des_encrypt(struct skcipher_request *areq)
454*4882a593Smuzhiyun {
455*4882a593Smuzhiyun struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
456*4882a593Smuzhiyun struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);
457*4882a593Smuzhiyun struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);
458*4882a593Smuzhiyun
459*4882a593Smuzhiyun rctx->mode = SS_OP_DES | SS_ECB | SS_ENABLED | SS_ENCRYPTION |
460*4882a593Smuzhiyun op->keymode;
461*4882a593Smuzhiyun return sun4i_ss_cipher_poll(areq);
462*4882a593Smuzhiyun }
463*4882a593Smuzhiyun
sun4i_ss_ecb_des_decrypt(struct skcipher_request * areq)464*4882a593Smuzhiyun int sun4i_ss_ecb_des_decrypt(struct skcipher_request *areq)
465*4882a593Smuzhiyun {
466*4882a593Smuzhiyun struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
467*4882a593Smuzhiyun struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);
468*4882a593Smuzhiyun struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);
469*4882a593Smuzhiyun
470*4882a593Smuzhiyun rctx->mode = SS_OP_DES | SS_ECB | SS_ENABLED | SS_DECRYPTION |
471*4882a593Smuzhiyun op->keymode;
472*4882a593Smuzhiyun return sun4i_ss_cipher_poll(areq);
473*4882a593Smuzhiyun }
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun /* CBC 3DES */
sun4i_ss_cbc_des3_encrypt(struct skcipher_request * areq)476*4882a593Smuzhiyun int sun4i_ss_cbc_des3_encrypt(struct skcipher_request *areq)
477*4882a593Smuzhiyun {
478*4882a593Smuzhiyun struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
479*4882a593Smuzhiyun struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);
480*4882a593Smuzhiyun struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun rctx->mode = SS_OP_3DES | SS_CBC | SS_ENABLED | SS_ENCRYPTION |
483*4882a593Smuzhiyun op->keymode;
484*4882a593Smuzhiyun return sun4i_ss_cipher_poll(areq);
485*4882a593Smuzhiyun }
486*4882a593Smuzhiyun
sun4i_ss_cbc_des3_decrypt(struct skcipher_request * areq)487*4882a593Smuzhiyun int sun4i_ss_cbc_des3_decrypt(struct skcipher_request *areq)
488*4882a593Smuzhiyun {
489*4882a593Smuzhiyun struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
490*4882a593Smuzhiyun struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);
491*4882a593Smuzhiyun struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun rctx->mode = SS_OP_3DES | SS_CBC | SS_ENABLED | SS_DECRYPTION |
494*4882a593Smuzhiyun op->keymode;
495*4882a593Smuzhiyun return sun4i_ss_cipher_poll(areq);
496*4882a593Smuzhiyun }
497*4882a593Smuzhiyun
498*4882a593Smuzhiyun /* ECB 3DES */
sun4i_ss_ecb_des3_encrypt(struct skcipher_request * areq)499*4882a593Smuzhiyun int sun4i_ss_ecb_des3_encrypt(struct skcipher_request *areq)
500*4882a593Smuzhiyun {
501*4882a593Smuzhiyun struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
502*4882a593Smuzhiyun struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);
503*4882a593Smuzhiyun struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);
504*4882a593Smuzhiyun
505*4882a593Smuzhiyun rctx->mode = SS_OP_3DES | SS_ECB | SS_ENABLED | SS_ENCRYPTION |
506*4882a593Smuzhiyun op->keymode;
507*4882a593Smuzhiyun return sun4i_ss_cipher_poll(areq);
508*4882a593Smuzhiyun }
509*4882a593Smuzhiyun
sun4i_ss_ecb_des3_decrypt(struct skcipher_request * areq)510*4882a593Smuzhiyun int sun4i_ss_ecb_des3_decrypt(struct skcipher_request *areq)
511*4882a593Smuzhiyun {
512*4882a593Smuzhiyun struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
513*4882a593Smuzhiyun struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);
514*4882a593Smuzhiyun struct sun4i_cipher_req_ctx *rctx = skcipher_request_ctx(areq);
515*4882a593Smuzhiyun
516*4882a593Smuzhiyun rctx->mode = SS_OP_3DES | SS_ECB | SS_ENABLED | SS_DECRYPTION |
517*4882a593Smuzhiyun op->keymode;
518*4882a593Smuzhiyun return sun4i_ss_cipher_poll(areq);
519*4882a593Smuzhiyun }
520*4882a593Smuzhiyun
sun4i_ss_cipher_init(struct crypto_tfm * tfm)521*4882a593Smuzhiyun int sun4i_ss_cipher_init(struct crypto_tfm *tfm)
522*4882a593Smuzhiyun {
523*4882a593Smuzhiyun struct sun4i_tfm_ctx *op = crypto_tfm_ctx(tfm);
524*4882a593Smuzhiyun struct sun4i_ss_alg_template *algt;
525*4882a593Smuzhiyun const char *name = crypto_tfm_alg_name(tfm);
526*4882a593Smuzhiyun int err;
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun memset(op, 0, sizeof(struct sun4i_tfm_ctx));
529*4882a593Smuzhiyun
530*4882a593Smuzhiyun algt = container_of(tfm->__crt_alg, struct sun4i_ss_alg_template,
531*4882a593Smuzhiyun alg.crypto.base);
532*4882a593Smuzhiyun op->ss = algt->ss;
533*4882a593Smuzhiyun
534*4882a593Smuzhiyun op->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK);
535*4882a593Smuzhiyun if (IS_ERR(op->fallback_tfm)) {
536*4882a593Smuzhiyun dev_err(op->ss->dev, "ERROR: Cannot allocate fallback for %s %ld\n",
537*4882a593Smuzhiyun name, PTR_ERR(op->fallback_tfm));
538*4882a593Smuzhiyun return PTR_ERR(op->fallback_tfm);
539*4882a593Smuzhiyun }
540*4882a593Smuzhiyun
541*4882a593Smuzhiyun crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm),
542*4882a593Smuzhiyun sizeof(struct sun4i_cipher_req_ctx) +
543*4882a593Smuzhiyun crypto_skcipher_reqsize(op->fallback_tfm));
544*4882a593Smuzhiyun
545*4882a593Smuzhiyun
546*4882a593Smuzhiyun err = pm_runtime_get_sync(op->ss->dev);
547*4882a593Smuzhiyun if (err < 0)
548*4882a593Smuzhiyun goto error_pm;
549*4882a593Smuzhiyun
550*4882a593Smuzhiyun return 0;
551*4882a593Smuzhiyun error_pm:
552*4882a593Smuzhiyun crypto_free_skcipher(op->fallback_tfm);
553*4882a593Smuzhiyun return err;
554*4882a593Smuzhiyun }
555*4882a593Smuzhiyun
sun4i_ss_cipher_exit(struct crypto_tfm * tfm)556*4882a593Smuzhiyun void sun4i_ss_cipher_exit(struct crypto_tfm *tfm)
557*4882a593Smuzhiyun {
558*4882a593Smuzhiyun struct sun4i_tfm_ctx *op = crypto_tfm_ctx(tfm);
559*4882a593Smuzhiyun
560*4882a593Smuzhiyun crypto_free_skcipher(op->fallback_tfm);
561*4882a593Smuzhiyun pm_runtime_put(op->ss->dev);
562*4882a593Smuzhiyun }
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun /* check and set the AES key, prepare the mode to be used */
sun4i_ss_aes_setkey(struct crypto_skcipher * tfm,const u8 * key,unsigned int keylen)565*4882a593Smuzhiyun int sun4i_ss_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
566*4882a593Smuzhiyun unsigned int keylen)
567*4882a593Smuzhiyun {
568*4882a593Smuzhiyun struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);
569*4882a593Smuzhiyun struct sun4i_ss_ctx *ss = op->ss;
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun switch (keylen) {
572*4882a593Smuzhiyun case 128 / 8:
573*4882a593Smuzhiyun op->keymode = SS_AES_128BITS;
574*4882a593Smuzhiyun break;
575*4882a593Smuzhiyun case 192 / 8:
576*4882a593Smuzhiyun op->keymode = SS_AES_192BITS;
577*4882a593Smuzhiyun break;
578*4882a593Smuzhiyun case 256 / 8:
579*4882a593Smuzhiyun op->keymode = SS_AES_256BITS;
580*4882a593Smuzhiyun break;
581*4882a593Smuzhiyun default:
582*4882a593Smuzhiyun dev_dbg(ss->dev, "ERROR: Invalid keylen %u\n", keylen);
583*4882a593Smuzhiyun return -EINVAL;
584*4882a593Smuzhiyun }
585*4882a593Smuzhiyun op->keylen = keylen;
586*4882a593Smuzhiyun memcpy(op->key, key, keylen);
587*4882a593Smuzhiyun
588*4882a593Smuzhiyun crypto_skcipher_clear_flags(op->fallback_tfm, CRYPTO_TFM_REQ_MASK);
589*4882a593Smuzhiyun crypto_skcipher_set_flags(op->fallback_tfm, tfm->base.crt_flags & CRYPTO_TFM_REQ_MASK);
590*4882a593Smuzhiyun
591*4882a593Smuzhiyun return crypto_skcipher_setkey(op->fallback_tfm, key, keylen);
592*4882a593Smuzhiyun }
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun /* check and set the DES key, prepare the mode to be used */
sun4i_ss_des_setkey(struct crypto_skcipher * tfm,const u8 * key,unsigned int keylen)595*4882a593Smuzhiyun int sun4i_ss_des_setkey(struct crypto_skcipher *tfm, const u8 *key,
596*4882a593Smuzhiyun unsigned int keylen)
597*4882a593Smuzhiyun {
598*4882a593Smuzhiyun struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);
599*4882a593Smuzhiyun int err;
600*4882a593Smuzhiyun
601*4882a593Smuzhiyun err = verify_skcipher_des_key(tfm, key);
602*4882a593Smuzhiyun if (err)
603*4882a593Smuzhiyun return err;
604*4882a593Smuzhiyun
605*4882a593Smuzhiyun op->keylen = keylen;
606*4882a593Smuzhiyun memcpy(op->key, key, keylen);
607*4882a593Smuzhiyun
608*4882a593Smuzhiyun crypto_skcipher_clear_flags(op->fallback_tfm, CRYPTO_TFM_REQ_MASK);
609*4882a593Smuzhiyun crypto_skcipher_set_flags(op->fallback_tfm, tfm->base.crt_flags & CRYPTO_TFM_REQ_MASK);
610*4882a593Smuzhiyun
611*4882a593Smuzhiyun return crypto_skcipher_setkey(op->fallback_tfm, key, keylen);
612*4882a593Smuzhiyun }
613*4882a593Smuzhiyun
614*4882a593Smuzhiyun /* check and set the 3DES key, prepare the mode to be used */
sun4i_ss_des3_setkey(struct crypto_skcipher * tfm,const u8 * key,unsigned int keylen)615*4882a593Smuzhiyun int sun4i_ss_des3_setkey(struct crypto_skcipher *tfm, const u8 *key,
616*4882a593Smuzhiyun unsigned int keylen)
617*4882a593Smuzhiyun {
618*4882a593Smuzhiyun struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);
619*4882a593Smuzhiyun int err;
620*4882a593Smuzhiyun
621*4882a593Smuzhiyun err = verify_skcipher_des3_key(tfm, key);
622*4882a593Smuzhiyun if (err)
623*4882a593Smuzhiyun return err;
624*4882a593Smuzhiyun
625*4882a593Smuzhiyun op->keylen = keylen;
626*4882a593Smuzhiyun memcpy(op->key, key, keylen);
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun crypto_skcipher_clear_flags(op->fallback_tfm, CRYPTO_TFM_REQ_MASK);
629*4882a593Smuzhiyun crypto_skcipher_set_flags(op->fallback_tfm, tfm->base.crt_flags & CRYPTO_TFM_REQ_MASK);
630*4882a593Smuzhiyun
631*4882a593Smuzhiyun return crypto_skcipher_setkey(op->fallback_tfm, key, keylen);
632*4882a593Smuzhiyun
633*4882a593Smuzhiyun }
634