]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - crypto/cts.c
Merge branch 'stmmac-fixes'
[linux.git] / crypto / cts.c
index 4e28d83ae37da025b5eef7f9506df6bf5bdb9ca1..48188adc8e91c3407cda1b7549ecf9f96eaf8ac3 100644 (file)
@@ -78,15 +78,11 @@ static int crypto_cts_setkey(struct crypto_skcipher *parent, const u8 *key,
 {
        struct crypto_cts_ctx *ctx = crypto_skcipher_ctx(parent);
        struct crypto_skcipher *child = ctx->child;
-       int err;
 
        crypto_skcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
        crypto_skcipher_set_flags(child, crypto_skcipher_get_flags(parent) &
                                         CRYPTO_TFM_REQ_MASK);
-       err = crypto_skcipher_setkey(child, key, keylen);
-       crypto_skcipher_set_flags(parent, crypto_skcipher_get_flags(child) &
-                                         CRYPTO_TFM_RES_MASK);
-       return err;
+       return crypto_skcipher_setkey(child, key, keylen);
 }
 
 static void cts_cbc_crypt_done(struct crypto_async_request *areq, int err)
@@ -152,12 +148,14 @@ static int crypto_cts_encrypt(struct skcipher_request *req)
        struct skcipher_request *subreq = &rctx->subreq;
        int bsize = crypto_skcipher_blocksize(tfm);
        unsigned int nbytes = req->cryptlen;
-       int cbc_blocks = (nbytes + bsize - 1) / bsize - 1;
        unsigned int offset;
 
        skcipher_request_set_tfm(subreq, ctx->child);
 
-       if (cbc_blocks <= 0) {
+       if (nbytes < bsize)
+               return -EINVAL;
+
+       if (nbytes == bsize) {
                skcipher_request_set_callback(subreq, req->base.flags,
                                              req->base.complete,
                                              req->base.data);
@@ -166,7 +164,7 @@ static int crypto_cts_encrypt(struct skcipher_request *req)
                return crypto_skcipher_encrypt(subreq);
        }
 
-       offset = cbc_blocks * bsize;
+       offset = rounddown(nbytes - 1, bsize);
        rctx->offset = offset;
 
        skcipher_request_set_callback(subreq, req->base.flags,
@@ -244,13 +242,15 @@ static int crypto_cts_decrypt(struct skcipher_request *req)
        struct skcipher_request *subreq = &rctx->subreq;
        int bsize = crypto_skcipher_blocksize(tfm);
        unsigned int nbytes = req->cryptlen;
-       int cbc_blocks = (nbytes + bsize - 1) / bsize - 1;
        unsigned int offset;
        u8 *space;
 
        skcipher_request_set_tfm(subreq, ctx->child);
 
-       if (cbc_blocks <= 0) {
+       if (nbytes < bsize)
+               return -EINVAL;
+
+       if (nbytes == bsize) {
                skcipher_request_set_callback(subreq, req->base.flags,
                                              req->base.complete,
                                              req->base.data);
@@ -264,10 +264,10 @@ static int crypto_cts_decrypt(struct skcipher_request *req)
 
        space = crypto_cts_reqctx_space(req);
 
-       offset = cbc_blocks * bsize;
+       offset = rounddown(nbytes - 1, bsize);
        rctx->offset = offset;
 
-       if (cbc_blocks <= 1)
+       if (offset <= bsize)
                memcpy(space, req->iv, bsize);
        else
                scatterwalk_map_and_copy(space, req->src, offset - 2 * bsize,
@@ -328,6 +328,7 @@ static int crypto_cts_create(struct crypto_template *tmpl, struct rtattr **tb)
        struct crypto_attr_type *algt;
        struct skcipher_alg *alg;
        const char *cipher_name;
+       u32 mask;
        int err;
 
        algt = crypto_get_attr_type(tb);
@@ -337,6 +338,8 @@ static int crypto_cts_create(struct crypto_template *tmpl, struct rtattr **tb)
        if ((algt->type ^ CRYPTO_ALG_TYPE_SKCIPHER) & algt->mask)
                return -EINVAL;
 
+       mask = crypto_requires_sync(algt->type, algt->mask);
+
        cipher_name = crypto_attr_alg_name(tb[1]);
        if (IS_ERR(cipher_name))
                return PTR_ERR(cipher_name);
@@ -347,10 +350,8 @@ static int crypto_cts_create(struct crypto_template *tmpl, struct rtattr **tb)
 
        spawn = skcipher_instance_ctx(inst);
 
-       crypto_set_skcipher_spawn(spawn, skcipher_crypto_instance(inst));
-       err = crypto_grab_skcipher(spawn, cipher_name, 0,
-                                  crypto_requires_sync(algt->type,
-                                                       algt->mask));
+       err = crypto_grab_skcipher(spawn, skcipher_crypto_instance(inst),
+                                  cipher_name, 0, mask);
        if (err)
                goto err_free_inst;
 
@@ -419,7 +420,7 @@ static void __exit crypto_cts_module_exit(void)
        crypto_unregister_template(&crypto_cts_tmpl);
 }
 
-module_init(crypto_cts_module_init);
+subsys_initcall(crypto_cts_module_init);
 module_exit(crypto_cts_module_exit);
 
 MODULE_LICENSE("Dual BSD/GPL");