[CRYPTO] cbc: Optimise in-place decryption This optimisation trades the cost of 2 copies per block versus 1 divide for each segment. The idea is simply to decrypt backwards. This way we avoid overwriting most IVs until we've used it. Testing with tcrypt shows a performance gain of 10%, making in-place decryption faster than in-place encryption for AES. Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> --- crypto/cbc.c | 23 +++++++++++++++-------- 1 files changed, 15 insertions(+), 8 deletions(-) diff --git a/crypto/cbc.c b/crypto/cbc.c --- a/crypto/cbc.c +++ b/crypto/cbc.c @@ -159,16 +159,23 @@ static int crypto_cbc_decrypt_inplace(st unsigned int nbytes = walk->nbytes; u8 *src = walk->src.virt.addr; u8 stack[bsize + alignmask]; - u8 *tmp = (u8 *)ALIGN((unsigned long)stack, alignmask + 1); + u8 *first_iv = (u8 *)ALIGN((unsigned long)stack, alignmask + 1); - do { - fn(crypto_cipher_tfm(tfm), tmp, src); - xor(tmp, walk->iv, bsize); - memcpy(walk->iv, src, bsize); - memcpy(src, tmp, bsize); + memcpy(first_iv, walk->iv, bsize); + + /* Start of the last block. */ + src += nbytes - nbytes % bsize - bsize; + memcpy(walk->iv, src, bsize); + + for (;;) { + fn(crypto_cipher_tfm(tfm), src, src); + if ((nbytes -= bsize) < bsize) + break; + xor(src, src - bsize, bsize); + src -= bsize; + } - src += bsize; - } while ((nbytes -= bsize) >= bsize); + xor(src, first_iv, bsize); return nbytes; } -- VGER BF report: H 0.0174255 - To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html