From: Horia Geantă horia.geanta@nxp.com
commit 3a5a9e1ef37b030b836d92df8264f840988f4a38 upstream.
HW generates a Data Size error for chacha20 requests that are not a multiple of 64B, since algorithm state (AS) does not have the FINAL bit set.
Since updating req->iv (for chaining) is not required, modify skcipher descriptors to set the FINAL bit for chacha20.
[Note that for skcipher decryption we know that ctx1_iv_off is 0, which allows for an optimization by not checking algorithm type, since append_dec_op1() sets FINAL bit for all algorithms except AES.]
Also drop the descriptor operations that save the IV. However, in order to keep code logic simple, things like S/G tables generation etc. are not touched.
Cc: stable@vger.kernel.org # v5.3+ Fixes: 334d37c9e263 ("crypto: caam - update IV using HW support") Signed-off-by: Horia Geantă horia.geanta@nxp.com Tested-by: Valentin Ciocoi Radulescu valentin.ciocoi@nxp.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/crypto/caam/caamalg_desc.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
--- a/drivers/crypto/caam/caamalg_desc.c +++ b/drivers/crypto/caam/caamalg_desc.c @@ -1379,6 +1379,9 @@ void cnstr_shdsc_skcipher_encap(u32 * co const u32 ctx1_iv_off) { u32 *key_jump_cmd; + u32 options = cdata->algtype | OP_ALG_AS_INIT | OP_ALG_ENCRYPT; + bool is_chacha20 = ((cdata->algtype & OP_ALG_ALGSEL_MASK) == + OP_ALG_ALGSEL_CHACHA20);
init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX); /* Skip if already shared */ @@ -1417,14 +1420,15 @@ void cnstr_shdsc_skcipher_encap(u32 * co LDST_OFFSET_SHIFT));
/* Load operation */ - append_operation(desc, cdata->algtype | OP_ALG_AS_INIT | - OP_ALG_ENCRYPT); + if (is_chacha20) + options |= OP_ALG_AS_FINALIZE; + append_operation(desc, options);
/* Perform operation */ skcipher_append_src_dst(desc);
/* Store IV */ - if (ivsize) + if (!is_chacha20 && ivsize) append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT)); @@ -1451,6 +1455,8 @@ void cnstr_shdsc_skcipher_decap(u32 * co const u32 ctx1_iv_off) { u32 *key_jump_cmd; + bool is_chacha20 = ((cdata->algtype & OP_ALG_ALGSEL_MASK) == + OP_ALG_ALGSEL_CHACHA20);
init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX); /* Skip if already shared */ @@ -1499,7 +1505,7 @@ void cnstr_shdsc_skcipher_decap(u32 * co skcipher_append_src_dst(desc);
/* Store IV */ - if (ivsize) + if (!is_chacha20 && ivsize) append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT));