Lines Matching +full:sl3516 +full:- +full:crypto
1 // SPDX-License-Identifier: GPL-2.0
3 * sl3516-ce-cipher.c - hardware cryptographic offloader for Storlink SL3516 SoC
11 #include <linux/crypto.h>
12 #include <linux/dma-mapping.h>
16 #include <crypto/scatterwalk.h>
17 #include <crypto/internal/skcipher.h>
18 #include "sl3516-ce.h"
20 /* sl3516_ce_need_fallback - check if a request can be handled by the CE */
25 struct sl3516_ce_dev *ce = op->ce; in sl3516_ce_need_fallback()
30 if (areq->cryptlen == 0 || areq->cryptlen % 16) { in sl3516_ce_need_fallback()
31 ce->fallback_mod16++; in sl3516_ce_need_fallback()
39 if (sg_nents(areq->src) > MAXDESC / 2) { in sl3516_ce_need_fallback()
40 ce->fallback_sg_count_tx++; in sl3516_ce_need_fallback()
44 if (sg_nents(areq->dst) > MAXDESC) { in sl3516_ce_need_fallback()
45 ce->fallback_sg_count_rx++; in sl3516_ce_need_fallback()
49 sg = areq->src; in sl3516_ce_need_fallback()
51 if ((sg->length % 16) != 0) { in sl3516_ce_need_fallback()
52 ce->fallback_mod16++; in sl3516_ce_need_fallback()
56 ce->fallback_mod16++; in sl3516_ce_need_fallback()
59 if (!IS_ALIGNED(sg->offset, 16)) { in sl3516_ce_need_fallback()
60 ce->fallback_align16++; in sl3516_ce_need_fallback()
65 sg = areq->dst; in sl3516_ce_need_fallback()
67 if ((sg->length % 16) != 0) { in sl3516_ce_need_fallback()
68 ce->fallback_mod16++; in sl3516_ce_need_fallback()
72 ce->fallback_mod16++; in sl3516_ce_need_fallback()
75 if (!IS_ALIGNED(sg->offset, 16)) { in sl3516_ce_need_fallback()
76 ce->fallback_align16++; in sl3516_ce_need_fallback()
83 in_sg = areq->src; in sl3516_ce_need_fallback()
84 out_sg = areq->dst; in sl3516_ce_need_fallback()
86 if (in_sg->length != out_sg->length) { in sl3516_ce_need_fallback()
87 ce->fallback_not_same_len++; in sl3516_ce_need_fallback()
109 algt->stat_fb++; in sl3516_ce_cipher_fallback()
111 skcipher_request_set_tfm(&rctx->fallback_req, op->fallback_tfm); in sl3516_ce_cipher_fallback()
112 skcipher_request_set_callback(&rctx->fallback_req, areq->base.flags, in sl3516_ce_cipher_fallback()
113 areq->base.complete, areq->base.data); in sl3516_ce_cipher_fallback()
114 skcipher_request_set_crypt(&rctx->fallback_req, areq->src, areq->dst, in sl3516_ce_cipher_fallback()
115 areq->cryptlen, areq->iv); in sl3516_ce_cipher_fallback()
116 if (rctx->op_dir == CE_DECRYPTION) in sl3516_ce_cipher_fallback()
117 err = crypto_skcipher_decrypt(&rctx->fallback_req); in sl3516_ce_cipher_fallback()
119 err = crypto_skcipher_encrypt(&rctx->fallback_req); in sl3516_ce_cipher_fallback()
127 struct sl3516_ce_dev *ce = op->ce; in sl3516_ce_cipher()
141 dev_dbg(ce->dev, "%s %s %u %x IV(%p %u) key=%u\n", __func__, in sl3516_ce_cipher()
142 crypto_tfm_alg_name(areq->base.tfm), in sl3516_ce_cipher()
143 areq->cryptlen, in sl3516_ce_cipher()
144 rctx->op_dir, areq->iv, crypto_skcipher_ivsize(tfm), in sl3516_ce_cipher()
145 op->keylen); in sl3516_ce_cipher()
147 algt->stat_req++; in sl3516_ce_cipher()
149 if (areq->src == areq->dst) { in sl3516_ce_cipher()
150 nr_sgs = dma_map_sg(ce->dev, areq->src, sg_nents(areq->src), in sl3516_ce_cipher()
153 dev_err(ce->dev, "Invalid sg number %d\n", nr_sgs); in sl3516_ce_cipher()
154 err = -EINVAL; in sl3516_ce_cipher()
159 nr_sgs = dma_map_sg(ce->dev, areq->src, sg_nents(areq->src), in sl3516_ce_cipher()
162 dev_err(ce->dev, "Invalid sg number %d\n", nr_sgs); in sl3516_ce_cipher()
163 err = -EINVAL; in sl3516_ce_cipher()
166 nr_sgd = dma_map_sg(ce->dev, areq->dst, sg_nents(areq->dst), in sl3516_ce_cipher()
169 dev_err(ce->dev, "Invalid sg number %d\n", nr_sgd); in sl3516_ce_cipher()
170 err = -EINVAL; in sl3516_ce_cipher()
175 len = areq->cryptlen; in sl3516_ce_cipher()
177 sg = areq->src; in sl3516_ce_cipher()
181 rctx->t_src[i].addr = sg_dma_address(sg); in sl3516_ce_cipher()
183 rctx->t_src[i].len = todo; in sl3516_ce_cipher()
184 dev_dbg(ce->dev, "%s total=%u SGS(%d %u off=%d) todo=%u\n", __func__, in sl3516_ce_cipher()
185 areq->cryptlen, i, rctx->t_src[i].len, sg->offset, todo); in sl3516_ce_cipher()
186 len -= todo; in sl3516_ce_cipher()
192 dev_err(ce->dev, "remaining len %d/%u nr_sgs=%d\n", len, areq->cryptlen, nr_sgs); in sl3516_ce_cipher()
193 err = -EINVAL; in sl3516_ce_cipher()
197 len = areq->cryptlen; in sl3516_ce_cipher()
199 sg = areq->dst; in sl3516_ce_cipher()
203 rctx->t_dst[i].addr = sg_dma_address(sg); in sl3516_ce_cipher()
205 rctx->t_dst[i].len = todo; in sl3516_ce_cipher()
206 dev_dbg(ce->dev, "%s total=%u SGD(%d %u off=%d) todo=%u\n", __func__, in sl3516_ce_cipher()
207 areq->cryptlen, i, rctx->t_dst[i].len, sg->offset, todo); in sl3516_ce_cipher()
208 len -= todo; in sl3516_ce_cipher()
215 dev_err(ce->dev, "remaining len %d\n", len); in sl3516_ce_cipher()
216 err = -EINVAL; in sl3516_ce_cipher()
220 switch (algt->mode) { in sl3516_ce_cipher()
222 rctx->pctrllen = sizeof(struct pkt_control_ecb); in sl3516_ce_cipher()
223 ecb = (struct pkt_control_ecb *)ce->pctrl; in sl3516_ce_cipher()
225 rctx->tqflag = TQ0_TYPE_CTRL; in sl3516_ce_cipher()
226 rctx->tqflag |= TQ1_CIPHER; in sl3516_ce_cipher()
227 ecb->control.op_mode = rctx->op_dir; in sl3516_ce_cipher()
228 ecb->control.cipher_algorithm = ECB_AES; in sl3516_ce_cipher()
229 ecb->cipher.header_len = 0; in sl3516_ce_cipher()
230 ecb->cipher.algorithm_len = areq->cryptlen; in sl3516_ce_cipher()
231 cpu_to_be32_array((__be32 *)ecb->key, (u32 *)op->key, op->keylen / 4); in sl3516_ce_cipher()
232 rctx->h = &ecb->cipher; in sl3516_ce_cipher()
234 rctx->tqflag |= TQ4_KEY0; in sl3516_ce_cipher()
235 rctx->tqflag |= TQ5_KEY4; in sl3516_ce_cipher()
236 rctx->tqflag |= TQ6_KEY6; in sl3516_ce_cipher()
237 ecb->control.aesnk = op->keylen / 4; in sl3516_ce_cipher()
241 rctx->nr_sgs = nr_sgs; in sl3516_ce_cipher()
242 rctx->nr_sgd = nr_sgd; in sl3516_ce_cipher()
243 err = sl3516_ce_run_task(ce, rctx, crypto_tfm_alg_name(areq->base.tfm)); in sl3516_ce_cipher()
246 if (areq->src == areq->dst) { in sl3516_ce_cipher()
247 dma_unmap_sg(ce->dev, areq->src, sg_nents(areq->src), in sl3516_ce_cipher()
250 dma_unmap_sg(ce->dev, areq->src, sg_nents(areq->src), in sl3516_ce_cipher()
252 dma_unmap_sg(ce->dev, areq->dst, sg_nents(areq->dst), in sl3516_ce_cipher()
282 rctx->op_dir = CE_DECRYPTION; in sl3516_ce_skdecrypt()
287 engine = op->ce->engine; in sl3516_ce_skdecrypt()
300 rctx->op_dir = CE_ENCRYPTION; in sl3516_ce_skencrypt()
305 engine = op->ce->engine; in sl3516_ce_skencrypt()
322 op->ce = algt->ce; in sl3516_ce_cipher_init()
324 op->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK); in sl3516_ce_cipher_init()
325 if (IS_ERR(op->fallback_tfm)) { in sl3516_ce_cipher_init()
326 dev_err(op->ce->dev, "ERROR: Cannot allocate fallback for %s %ld\n", in sl3516_ce_cipher_init()
327 name, PTR_ERR(op->fallback_tfm)); in sl3516_ce_cipher_init()
328 return PTR_ERR(op->fallback_tfm); in sl3516_ce_cipher_init()
331 sktfm->reqsize = sizeof(struct sl3516_ce_cipher_req_ctx) + in sl3516_ce_cipher_init()
332 crypto_skcipher_reqsize(op->fallback_tfm); in sl3516_ce_cipher_init()
334 dev_info(op->ce->dev, "Fallback for %s is %s\n", in sl3516_ce_cipher_init()
335 crypto_tfm_alg_driver_name(&sktfm->base), in sl3516_ce_cipher_init()
336 crypto_tfm_alg_driver_name(crypto_skcipher_tfm(op->fallback_tfm))); in sl3516_ce_cipher_init()
338 op->enginectx.op.do_one_request = sl3516_ce_handle_cipher_request; in sl3516_ce_cipher_init()
339 op->enginectx.op.prepare_request = NULL; in sl3516_ce_cipher_init()
340 op->enginectx.op.unprepare_request = NULL; in sl3516_ce_cipher_init()
342 err = pm_runtime_get_sync(op->ce->dev); in sl3516_ce_cipher_init()
348 pm_runtime_put_noidle(op->ce->dev); in sl3516_ce_cipher_init()
349 crypto_free_skcipher(op->fallback_tfm); in sl3516_ce_cipher_init()
357 kfree_sensitive(op->key); in sl3516_ce_cipher_exit()
358 crypto_free_skcipher(op->fallback_tfm); in sl3516_ce_cipher_exit()
359 pm_runtime_put_sync_suspend(op->ce->dev); in sl3516_ce_cipher_exit()
366 struct sl3516_ce_dev *ce = op->ce; in sl3516_ce_aes_setkey()
376 dev_dbg(ce->dev, "ERROR: Invalid keylen %u\n", keylen); in sl3516_ce_aes_setkey()
377 return -EINVAL; in sl3516_ce_aes_setkey()
379 kfree_sensitive(op->key); in sl3516_ce_aes_setkey()
380 op->keylen = keylen; in sl3516_ce_aes_setkey()
381 op->key = kmemdup(key, keylen, GFP_KERNEL | GFP_DMA); in sl3516_ce_aes_setkey()
382 if (!op->key) in sl3516_ce_aes_setkey()
383 return -ENOMEM; in sl3516_ce_aes_setkey()
385 crypto_skcipher_clear_flags(op->fallback_tfm, CRYPTO_TFM_REQ_MASK); in sl3516_ce_aes_setkey()
386 crypto_skcipher_set_flags(op->fallback_tfm, tfm->base.crt_flags & CRYPTO_TFM_REQ_MASK); in sl3516_ce_aes_setkey()
388 return crypto_skcipher_setkey(op->fallback_tfm, key, keylen); in sl3516_ce_aes_setkey()