The SGL can directly operate caller-provided memory with the exception of stack memory. The DRBG detects whether the caller provided non-suitable memory and uses the scratchpad only on those circumstances. This patch increases the speed of the CTR DRBG by 1 to 3 percent depending on the buffer size of the output buffer. Signed-off-by: Stephan Mueller <smueller@xxxxxxxxxx> --- crypto/drbg.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/crypto/drbg.c b/crypto/drbg.c index ee302fd229ad..193354e9d207 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -1748,14 +1748,20 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg, { struct scatterlist *sg_in = &drbg->sg_in, *sg_out = &drbg->sg_out; int ret; + bool virt_addr_valid = virt_addr_valid(outbuf); sg_set_buf(sg_in, inbuf, inlen); - sg_set_buf(sg_out, drbg->outscratchpad, DRBG_OUTSCRATCHLEN); while (outlen) { - u32 cryptlen = min3(inlen, outlen, (u32)DRBG_OUTSCRATCHLEN); + u32 cryptlen = min_t(u32, inlen, outlen); /* Output buffer may not be valid for SGL, use scratchpad */ + if (virt_addr_valid) { + sg_set_buf(sg_out, outbuf, cryptlen); + } else { + cryptlen = min_t(u32, cryptlen, DRBG_OUTSCRATCHLEN); + sg_set_buf(sg_out, drbg->outscratchpad, cryptlen); + } skcipher_request_set_crypt(drbg->ctr_req, sg_in, sg_out, cryptlen, drbg->V); ret = crypto_wait_req(crypto_skcipher_encrypt(drbg->ctr_req), @@ -1765,7 +1771,8 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg, crypto_init_wait(&drbg->ctr_wait); - memcpy(outbuf, drbg->outscratchpad, cryptlen); + if (!virt_addr_valid) + memcpy(outbuf, drbg->outscratchpad, cryptlen); outlen -= cryptlen; outbuf += cryptlen; @@ -1773,7 +1780,8 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg, ret = 0; out: - memzero_explicit(drbg->outscratchpad, DRBG_OUTSCRATCHLEN); + if (!virt_addr_valid) + memzero_explicit(drbg->outscratchpad, DRBG_OUTSCRATCHLEN); return ret; } #endif /* CONFIG_CRYPTO_DRBG_CTR */ -- 2.17.1