As it stands rfc3686 cannot do chaining. That is, it has to handle each request as a whole. This patch adds support for chaining when the CRYPTO_TFM_REQ_MORE flag is set. Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> --- crypto/ctr.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/crypto/ctr.c b/crypto/ctr.c index c39fcffba27f5..eccfab07f2fbb 100644 --- a/crypto/ctr.c +++ b/crypto/ctr.c @@ -5,7 +5,6 @@ * (C) Copyright IBM Corp. 2007 - Joy Latten <latten@xxxxxxxxxx> */ -#include <crypto/algapi.h> #include <crypto/ctr.h> #include <crypto/internal/skcipher.h> #include <linux/err.h> @@ -21,7 +20,8 @@ struct crypto_rfc3686_ctx { struct crypto_rfc3686_req_ctx { u8 iv[CTR_RFC3686_BLOCK_SIZE]; - struct skcipher_request subreq CRYPTO_MINALIGN_ATTR; + bool init; + struct skcipher_request subreq; }; static void crypto_ctr_crypt_final(struct skcipher_walk *walk, @@ -197,6 +197,9 @@ static int crypto_rfc3686_crypt(struct skcipher_request *req) struct skcipher_request *subreq = &rctx->subreq; u8 *iv = rctx->iv; + if (rctx->init) + goto skip_init; + /* set up counter block */ memcpy(iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE); memcpy(iv + CTR_RFC3686_NONCE_SIZE, req->iv, CTR_RFC3686_IV_SIZE); @@ -205,6 +208,9 @@ static int crypto_rfc3686_crypt(struct skcipher_request *req) *(__be32 *)(iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) = cpu_to_be32(1); +skip_init: + rctx->init = req->base.flags & CRYPTO_TFM_REQ_MORE; + skcipher_request_set_tfm(subreq, child); skcipher_request_set_callback(subreq, req->base.flags, req->base.complete, req->base.data);