@@ -57,12 +57,18 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
struct af_alg_ctx *ctx = ask->private;
struct crypto_skcipher *tfm = pask->private;
unsigned int bs = crypto_skcipher_chunksize(tfm);
+ unsigned int rflags = CRYPTO_TFM_REQ_MAY_SLEEP;
+ int fc = crypto_skcipher_fcsize(tfm);
struct af_alg_async_req *areq;
+ unsigned int min = bs;
int err = 0;
size_t len = 0;
- if (!ctx->init || (ctx->more && ctx->used < bs)) {
- err = af_alg_wait_for_data(sk, flags, bs);
+ if (fc >= 0)
+ min += fc;
+
+ if (!ctx->init || (ctx->more && ctx->used < min)) {
+ err = af_alg_wait_for_data(sk, flags, min);
if (err)
return err;
}
@@ -78,13 +84,22 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
if (err)
goto free;
+ err = -EINVAL;
+
/*
* If more buffers are to be expected to be processed, process only
- * full block size buffers.
+ * full block size buffers and withhold data according to fcsize.
*/
- if (ctx->more || len < ctx->used)
+ if (ctx->more || len < ctx->used) {
+ if (fc < 0)
+ goto free;
+
+ len -= fc;
len -= len % bs;
+ rflags |= CRYPTO_TFM_REQ_MORE;
+ }
+
/*
* Create a per request TX SGL for this request which tracks the
* SG entries from the global TX SGL.
@@ -116,8 +131,7 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
areq->outlen = len;
skcipher_request_set_callback(&areq->cra_u.skcipher_req,
- CRYPTO_TFM_REQ_MAY_SLEEP,
- af_alg_async_cb, areq);
+ rflags, af_alg_async_cb, areq);
err = ctx->enc ?
crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) :
crypto_skcipher_decrypt(&areq->cra_u.skcipher_req);
@@ -129,9 +143,9 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
sock_put(sk);
} else {
/* Synchronous operation */
+ rflags |= CRYPTO_TFM_REQ_MAY_BACKLOG;
skcipher_request_set_callback(&areq->cra_u.skcipher_req,
- CRYPTO_TFM_REQ_MAY_SLEEP |
- CRYPTO_TFM_REQ_MAY_BACKLOG,
+ rflags,
crypto_req_done, &ctx->wait);
err = crypto_wait_req(ctx->enc ?
crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) :
As it stands algif_skcipher assumes all algorithms support chaining. This patch teaches it about the new fcsize attribute which can be used to disable chaining on a given algorithm. It can also be used to support chaining on algorithms such as cts that cannot otherwise do chaining. For that case algif_skcipher will also now set the request flag CRYPTO_TFM_REQ_MORE when needed. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> --- crypto/algif_skcipher.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-)