Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[sfrench/cifs-2.6.git] / drivers / crypto / caam / caamalg.c
index fde399c887798458e62270957cfca001237fdf72..0488b7f81dcf314ae0b9c37acf8ffd65efeb1c29 100644 (file)
@@ -882,10 +882,10 @@ static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
 {
        struct ablkcipher_request *req = context;
        struct ablkcipher_edesc *edesc;
-#ifdef DEBUG
        struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
        int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
 
+#ifdef DEBUG
        dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
 #endif
 
@@ -904,6 +904,14 @@ static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
 #endif
 
        ablkcipher_unmap(jrdev, edesc, req);
+
+       /*
+        * The crypto API expects us to set the IV (req->info) to the last
+        * ciphertext block. This is used e.g. by the CTS mode.
+        */
+       scatterwalk_map_and_copy(req->info, req->dst, req->nbytes - ivsize,
+                                ivsize, 0);
+
        kfree(edesc);
 
        ablkcipher_request_complete(req, err);
@@ -914,10 +922,10 @@ static void ablkcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
 {
        struct ablkcipher_request *req = context;
        struct ablkcipher_edesc *edesc;
-#ifdef DEBUG
        struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
        int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
 
+#ifdef DEBUG
        dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
 #endif
 
@@ -935,6 +943,14 @@ static void ablkcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
 #endif
 
        ablkcipher_unmap(jrdev, edesc, req);
+
+       /*
+        * The crypto API expects us to set the IV (req->info) to the last
+        * ciphertext block.
+        */
+       scatterwalk_map_and_copy(req->info, req->src, req->nbytes - ivsize,
+                                ivsize, 0);
+
        kfree(edesc);
 
        ablkcipher_request_complete(req, err);