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 <[email protected]>
---

 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 <[email protected]>
  */
 
-#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);

Reply via email to