mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
crypto: sun4i-ss - IV register does not work on A10 and A13
commit b756f1c8fc9d84e3f546d7ffe056c5352f4aab05 upstream.
Allwinner A10 and A13 SoC have a version of the SS which produce
invalid IV in IVx register.
Instead of adding a variant for those, let's convert SS to produce IV
directly from data.
Fixes: 6298e94821
("crypto: sunxi-ss - Add Allwinner Security System crypto accelerator")
Cc: <stable@vger.kernel.org>
Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
ca4460daf0
commit
19be286216
@ -20,6 +20,7 @@ static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
|
||||
unsigned int ivsize = crypto_skcipher_ivsize(tfm);
|
||||
struct sun4i_cipher_req_ctx *ctx = skcipher_request_ctx(areq);
|
||||
u32 mode = ctx->mode;
|
||||
void *backup_iv = NULL;
|
||||
/* when activating SS, the default FIFO space is SS_RX_DEFAULT(32) */
|
||||
u32 rx_cnt = SS_RX_DEFAULT;
|
||||
u32 tx_cnt = 0;
|
||||
@ -44,6 +45,13 @@ static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (areq->iv && ivsize > 0 && mode & SS_DECRYPTION) {
|
||||
backup_iv = kzalloc(ivsize, GFP_KERNEL);
|
||||
if (!backup_iv)
|
||||
return -ENOMEM;
|
||||
scatterwalk_map_and_copy(backup_iv, areq->src, areq->cryptlen - ivsize, ivsize, 0);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&ss->slock, flags);
|
||||
|
||||
for (i = 0; i < op->keylen; i += 4)
|
||||
@ -117,9 +125,12 @@ static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
|
||||
} while (oleft);
|
||||
|
||||
if (areq->iv) {
|
||||
for (i = 0; i < 4 && i < ivsize / 4; i++) {
|
||||
v = readl(ss->base + SS_IV0 + i * 4);
|
||||
*(u32 *)(areq->iv + i * 4) = v;
|
||||
if (mode & SS_DECRYPTION) {
|
||||
memcpy(areq->iv, backup_iv, ivsize);
|
||||
kfree_sensitive(backup_iv);
|
||||
} else {
|
||||
scatterwalk_map_and_copy(areq->iv, areq->dst, areq->cryptlen - ivsize,
|
||||
ivsize, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,6 +185,7 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
|
||||
unsigned int ileft = areq->cryptlen;
|
||||
unsigned int oleft = areq->cryptlen;
|
||||
unsigned int todo;
|
||||
void *backup_iv = NULL;
|
||||
struct sg_mapping_iter mi, mo;
|
||||
unsigned long pi = 0, po = 0; /* progress for in and out */
|
||||
bool miter_err;
|
||||
@ -217,6 +229,13 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
|
||||
if (need_fallback)
|
||||
return sun4i_ss_cipher_poll_fallback(areq);
|
||||
|
||||
if (areq->iv && ivsize > 0 && mode & SS_DECRYPTION) {
|
||||
backup_iv = kzalloc(ivsize, GFP_KERNEL);
|
||||
if (!backup_iv)
|
||||
return -ENOMEM;
|
||||
scatterwalk_map_and_copy(backup_iv, areq->src, areq->cryptlen - ivsize, ivsize, 0);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&ss->slock, flags);
|
||||
|
||||
for (i = 0; i < op->keylen; i += 4)
|
||||
@ -345,9 +364,12 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
|
||||
sg_miter_stop(&mo);
|
||||
}
|
||||
if (areq->iv) {
|
||||
for (i = 0; i < 4 && i < ivsize / 4; i++) {
|
||||
v = readl(ss->base + SS_IV0 + i * 4);
|
||||
*(u32 *)(areq->iv + i * 4) = v;
|
||||
if (mode & SS_DECRYPTION) {
|
||||
memcpy(areq->iv, backup_iv, ivsize);
|
||||
kfree_sensitive(backup_iv);
|
||||
} else {
|
||||
scatterwalk_map_and_copy(areq->iv, areq->dst, areq->cryptlen - ivsize,
|
||||
ivsize, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user