Lines Matching +full:op +full:- +full:mode
2 * sun4i-ss-cipher.c - hardware cryptographic accelerator for Allwinner A20 SoC
4 * Copyright (C) 2013-2015 Corentin LABBE <clabbe.montjoie@gmail.com>
7 * keysize in CBC and ECB mode.
8 * Add support also for DES and 3DES in CBC and ECB mode.
17 #include "sun4i-ss.h"
22 struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm); in sun4i_ss_opti_poll() local
23 struct sun4i_ss_ctx *ss = op->ss; in sun4i_ss_opti_poll()
26 u32 mode = ctx->mode; in sun4i_ss_opti_poll() local
34 unsigned int ileft = areq->cryptlen; in sun4i_ss_opti_poll()
35 unsigned int oleft = areq->cryptlen; in sun4i_ss_opti_poll()
41 if (!areq->cryptlen) in sun4i_ss_opti_poll()
44 if (!areq->iv) { in sun4i_ss_opti_poll()
45 dev_err_ratelimited(ss->dev, "ERROR: Empty IV\n"); in sun4i_ss_opti_poll()
46 return -EINVAL; in sun4i_ss_opti_poll()
49 if (!areq->src || !areq->dst) { in sun4i_ss_opti_poll()
50 dev_err_ratelimited(ss->dev, "ERROR: Some SGs are NULL\n"); in sun4i_ss_opti_poll()
51 return -EINVAL; in sun4i_ss_opti_poll()
54 spin_lock_irqsave(&ss->slock, flags); in sun4i_ss_opti_poll()
56 for (i = 0; i < op->keylen; i += 4) in sun4i_ss_opti_poll()
57 writel(*(op->key + i / 4), ss->base + SS_KEY0 + i); in sun4i_ss_opti_poll()
59 if (areq->iv) { in sun4i_ss_opti_poll()
61 v = *(u32 *)(areq->iv + i * 4); in sun4i_ss_opti_poll()
62 writel(v, ss->base + SS_IV0 + i * 4); in sun4i_ss_opti_poll()
65 writel(mode, ss->base + SS_CTL); in sun4i_ss_opti_poll()
67 sg_miter_start(&mi, areq->src, sg_nents(areq->src), in sun4i_ss_opti_poll()
69 sg_miter_start(&mo, areq->dst, sg_nents(areq->dst), in sun4i_ss_opti_poll()
74 dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n"); in sun4i_ss_opti_poll()
75 err = -EINVAL; in sun4i_ss_opti_poll()
79 ileft = areq->cryptlen / 4; in sun4i_ss_opti_poll()
80 oleft = areq->cryptlen / 4; in sun4i_ss_opti_poll()
85 todo = min_t(size_t, todo, (mi.length - oi) / 4); in sun4i_ss_opti_poll()
87 ileft -= todo; in sun4i_ss_opti_poll()
88 writesl(ss->base + SS_RXFIFO, mi.addr + oi, todo); in sun4i_ss_opti_poll()
96 spaces = readl(ss->base + SS_FCSR); in sun4i_ss_opti_poll()
101 todo = min_t(size_t, todo, (mo.length - oo) / 4); in sun4i_ss_opti_poll()
103 oleft -= todo; in sun4i_ss_opti_poll()
104 readsl(ss->base + SS_TXFIFO, mo.addr + oo, todo); in sun4i_ss_opti_poll()
113 if (areq->iv) { in sun4i_ss_opti_poll()
115 v = readl(ss->base + SS_IV0 + i * 4); in sun4i_ss_opti_poll()
116 *(u32 *)(areq->iv + i * 4) = v; in sun4i_ss_opti_poll()
123 writel(0, ss->base + SS_CTL); in sun4i_ss_opti_poll()
124 spin_unlock_irqrestore(&ss->slock, flags); in sun4i_ss_opti_poll()
132 struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm); in sun4i_ss_cipher_poll() local
133 struct sun4i_ss_ctx *ss = op->ss; in sun4i_ss_cipher_poll()
135 struct scatterlist *in_sg = areq->src; in sun4i_ss_cipher_poll()
136 struct scatterlist *out_sg = areq->dst; in sun4i_ss_cipher_poll()
139 u32 mode = ctx->mode; in sun4i_ss_cipher_poll() local
147 unsigned int ileft = areq->cryptlen; in sun4i_ss_cipher_poll()
148 unsigned int oleft = areq->cryptlen; in sun4i_ss_cipher_poll()
159 if (!areq->cryptlen) in sun4i_ss_cipher_poll()
162 if (!areq->iv) { in sun4i_ss_cipher_poll()
163 dev_err_ratelimited(ss->dev, "ERROR: Empty IV\n"); in sun4i_ss_cipher_poll()
164 return -EINVAL; in sun4i_ss_cipher_poll()
167 if (!areq->src || !areq->dst) { in sun4i_ss_cipher_poll()
168 dev_err_ratelimited(ss->dev, "ERROR: Some SGs are NULL\n"); in sun4i_ss_cipher_poll()
169 return -EINVAL; in sun4i_ss_cipher_poll()
177 if (in_sg->length % 4) in sun4i_ss_cipher_poll()
182 if (out_sg->length % 4) in sun4i_ss_cipher_poll()
190 spin_lock_irqsave(&ss->slock, flags); in sun4i_ss_cipher_poll()
192 for (i = 0; i < op->keylen; i += 4) in sun4i_ss_cipher_poll()
193 writel(*(op->key + i / 4), ss->base + SS_KEY0 + i); in sun4i_ss_cipher_poll()
195 if (areq->iv) { in sun4i_ss_cipher_poll()
197 v = *(u32 *)(areq->iv + i * 4); in sun4i_ss_cipher_poll()
198 writel(v, ss->base + SS_IV0 + i * 4); in sun4i_ss_cipher_poll()
201 writel(mode, ss->base + SS_CTL); in sun4i_ss_cipher_poll()
203 sg_miter_start(&mi, areq->src, sg_nents(areq->src), in sun4i_ss_cipher_poll()
205 sg_miter_start(&mo, areq->dst, sg_nents(areq->dst), in sun4i_ss_cipher_poll()
210 dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n"); in sun4i_ss_cipher_poll()
211 err = -EINVAL; in sun4i_ss_cipher_poll()
214 ileft = areq->cryptlen; in sun4i_ss_cipher_poll()
215 oleft = areq->cryptlen; in sun4i_ss_cipher_poll()
226 todo = min_t(size_t, todo, (mi.length - oi) / 4); in sun4i_ss_cipher_poll()
228 writesl(ss->base + SS_RXFIFO, mi.addr + oi, in sun4i_ss_cipher_poll()
230 ileft -= todo * 4; in sun4i_ss_cipher_poll()
240 todo = min(rx_cnt * 4 - ob, ileft); in sun4i_ss_cipher_poll()
241 todo = min_t(size_t, todo, mi.length - oi); in sun4i_ss_cipher_poll()
243 ileft -= todo; in sun4i_ss_cipher_poll()
247 writesl(ss->base + SS_RXFIFO, buf, in sun4i_ss_cipher_poll()
258 spaces = readl(ss->base + SS_FCSR); in sun4i_ss_cipher_poll()
261 dev_dbg(ss->dev, in sun4i_ss_cipher_poll()
263 mode, in sun4i_ss_cipher_poll()
264 oi, mi.length, ileft, areq->cryptlen, rx_cnt, in sun4i_ss_cipher_poll()
265 oo, mo.length, oleft, areq->cryptlen, tx_cnt, ob); in sun4i_ss_cipher_poll()
271 todo = min_t(size_t, todo, (mo.length - oo) / 4); in sun4i_ss_cipher_poll()
273 readsl(ss->base + SS_TXFIFO, mo.addr + oo, todo); in sun4i_ss_cipher_poll()
274 oleft -= todo * 4; in sun4i_ss_cipher_poll()
285 readsl(ss->base + SS_TXFIFO, bufo, tx_cnt); in sun4i_ss_cipher_poll()
296 mo.length - oo, obl - obo); in sun4i_ss_cipher_poll()
298 oleft -= todo; in sun4i_ss_cipher_poll()
309 if (areq->iv) { in sun4i_ss_cipher_poll()
311 v = readl(ss->base + SS_IV0 + i * 4); in sun4i_ss_cipher_poll()
312 *(u32 *)(areq->iv + i * 4) = v; in sun4i_ss_cipher_poll()
319 writel(0, ss->base + SS_CTL); in sun4i_ss_cipher_poll()
320 spin_unlock_irqrestore(&ss->slock, flags); in sun4i_ss_cipher_poll()
329 struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm); in sun4i_ss_cbc_aes_encrypt() local
332 rctx->mode = SS_OP_AES | SS_CBC | SS_ENABLED | SS_ENCRYPTION | in sun4i_ss_cbc_aes_encrypt()
333 op->keymode; in sun4i_ss_cbc_aes_encrypt()
340 struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm); in sun4i_ss_cbc_aes_decrypt() local
343 rctx->mode = SS_OP_AES | SS_CBC | SS_ENABLED | SS_DECRYPTION | in sun4i_ss_cbc_aes_decrypt()
344 op->keymode; in sun4i_ss_cbc_aes_decrypt()
352 struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm); in sun4i_ss_ecb_aes_encrypt() local
355 rctx->mode = SS_OP_AES | SS_ECB | SS_ENABLED | SS_ENCRYPTION | in sun4i_ss_ecb_aes_encrypt()
356 op->keymode; in sun4i_ss_ecb_aes_encrypt()
363 struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm); in sun4i_ss_ecb_aes_decrypt() local
366 rctx->mode = SS_OP_AES | SS_ECB | SS_ENABLED | SS_DECRYPTION | in sun4i_ss_ecb_aes_decrypt()
367 op->keymode; in sun4i_ss_ecb_aes_decrypt()
375 struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm); in sun4i_ss_cbc_des_encrypt() local
378 rctx->mode = SS_OP_DES | SS_CBC | SS_ENABLED | SS_ENCRYPTION | in sun4i_ss_cbc_des_encrypt()
379 op->keymode; in sun4i_ss_cbc_des_encrypt()
386 struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm); in sun4i_ss_cbc_des_decrypt() local
389 rctx->mode = SS_OP_DES | SS_CBC | SS_ENABLED | SS_DECRYPTION | in sun4i_ss_cbc_des_decrypt()
390 op->keymode; in sun4i_ss_cbc_des_decrypt()
398 struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm); in sun4i_ss_ecb_des_encrypt() local
401 rctx->mode = SS_OP_DES | SS_ECB | SS_ENABLED | SS_ENCRYPTION | in sun4i_ss_ecb_des_encrypt()
402 op->keymode; in sun4i_ss_ecb_des_encrypt()
409 struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm); in sun4i_ss_ecb_des_decrypt() local
412 rctx->mode = SS_OP_DES | SS_ECB | SS_ENABLED | SS_DECRYPTION | in sun4i_ss_ecb_des_decrypt()
413 op->keymode; in sun4i_ss_ecb_des_decrypt()
421 struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm); in sun4i_ss_cbc_des3_encrypt() local
424 rctx->mode = SS_OP_3DES | SS_CBC | SS_ENABLED | SS_ENCRYPTION | in sun4i_ss_cbc_des3_encrypt()
425 op->keymode; in sun4i_ss_cbc_des3_encrypt()
432 struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm); in sun4i_ss_cbc_des3_decrypt() local
435 rctx->mode = SS_OP_3DES | SS_CBC | SS_ENABLED | SS_DECRYPTION | in sun4i_ss_cbc_des3_decrypt()
436 op->keymode; in sun4i_ss_cbc_des3_decrypt()
444 struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm); in sun4i_ss_ecb_des3_encrypt() local
447 rctx->mode = SS_OP_3DES | SS_ECB | SS_ENABLED | SS_ENCRYPTION | in sun4i_ss_ecb_des3_encrypt()
448 op->keymode; in sun4i_ss_ecb_des3_encrypt()
455 struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm); in sun4i_ss_ecb_des3_decrypt() local
458 rctx->mode = SS_OP_3DES | SS_ECB | SS_ENABLED | SS_DECRYPTION | in sun4i_ss_ecb_des3_decrypt()
459 op->keymode; in sun4i_ss_ecb_des3_decrypt()
465 struct sun4i_tfm_ctx *op = crypto_tfm_ctx(tfm); in sun4i_ss_cipher_init() local
468 memset(op, 0, sizeof(struct sun4i_tfm_ctx)); in sun4i_ss_cipher_init()
470 algt = container_of(tfm->__crt_alg, struct sun4i_ss_alg_template, in sun4i_ss_cipher_init()
472 op->ss = algt->ss; in sun4i_ss_cipher_init()
480 /* check and set the AES key, prepare the mode to be used */
484 struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm); in sun4i_ss_aes_setkey() local
485 struct sun4i_ss_ctx *ss = op->ss; in sun4i_ss_aes_setkey()
489 op->keymode = SS_AES_128BITS; in sun4i_ss_aes_setkey()
492 op->keymode = SS_AES_192BITS; in sun4i_ss_aes_setkey()
495 op->keymode = SS_AES_256BITS; in sun4i_ss_aes_setkey()
498 dev_err(ss->dev, "ERROR: Invalid keylen %u\n", keylen); in sun4i_ss_aes_setkey()
500 return -EINVAL; in sun4i_ss_aes_setkey()
502 op->keylen = keylen; in sun4i_ss_aes_setkey()
503 memcpy(op->key, key, keylen); in sun4i_ss_aes_setkey()
507 /* check and set the DES key, prepare the mode to be used */
511 struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm); in sun4i_ss_des_setkey() local
512 struct sun4i_ss_ctx *ss = op->ss; in sun4i_ss_des_setkey()
518 dev_err(ss->dev, "Invalid keylen %u\n", keylen); in sun4i_ss_des_setkey()
520 return -EINVAL; in sun4i_ss_des_setkey()
528 dev_dbg(ss->dev, "Weak key %u\n", keylen); in sun4i_ss_des_setkey()
529 return -EINVAL; in sun4i_ss_des_setkey()
532 op->keylen = keylen; in sun4i_ss_des_setkey()
533 memcpy(op->key, key, keylen); in sun4i_ss_des_setkey()
537 /* check and set the 3DES key, prepare the mode to be used */
541 struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm); in sun4i_ss_des3_setkey() local
542 struct sun4i_ss_ctx *ss = op->ss; in sun4i_ss_des3_setkey()
545 dev_err(ss->dev, "Invalid keylen %u\n", keylen); in sun4i_ss_des3_setkey()
547 return -EINVAL; in sun4i_ss_des3_setkey()
549 op->keylen = keylen; in sun4i_ss_des3_setkey()
550 memcpy(op->key, key, keylen); in sun4i_ss_des3_setkey()