ANDROID: crypto: allow blkcipher walks over ablkcipher data
authorEric Biggers <ebiggers@google.com>
Wed, 11 Jan 2017 00:47:49 +0000 (16:47 -0800)
committerAmit Pundir <amit.pundir@linaro.org>
Mon, 10 Apr 2017 07:42:16 +0000 (13:12 +0530)
Add a function blkcipher_ablkcipher_walk_virt() which allows ablkcipher
algorithms to use the blkcipher_walk API to walk over their data.  This
will be used by the HEH algorithm, which to support asynchronous ECB
algorithms will be an ablkcipher, but it also needs to make other passes
over the data.

Bug: 32975945
Signed-off-by: Eric Biggers <ebiggers@google.com>
Change-Id: I05f9a0e5473ba6115fcc72d5122d6b0b18b2078b

crypto/blkcipher.c
include/crypto/algapi.h

index dca7bc87dad9d326e39d44d1b62baad5006460da..7bbfadc195a64424ac238170f45e5ed5ca6cf3d4 100644 (file)
@@ -373,6 +373,27 @@ int blkcipher_aead_walk_virt_block(struct blkcipher_desc *desc,
 }
 EXPORT_SYMBOL_GPL(blkcipher_aead_walk_virt_block);
 
+/*
+ * This function allows ablkcipher algorithms to use the blkcipher_walk API to
+ * walk over their data.  The specified crypto_ablkcipher tfm is used to
+ * initialize the struct blkcipher_walk, and the crypto_blkcipher specified in
+ * desc->tfm is never used so it can be left NULL.  (Yes, this design is ugly,
+ * but it parallels blkcipher_aead_walk_virt_block() above.  In the 4.10 kernel
+ * this is starting to be cleaned up...)
+ */
+int blkcipher_ablkcipher_walk_virt(struct blkcipher_desc *desc,
+                                  struct blkcipher_walk *walk,
+                                  struct crypto_ablkcipher *tfm)
+{
+       walk->flags &= ~BLKCIPHER_WALK_PHYS;
+       walk->walk_blocksize = crypto_ablkcipher_blocksize(tfm);
+       walk->cipher_blocksize = walk->walk_blocksize;
+       walk->ivsize = crypto_ablkcipher_ivsize(tfm);
+       walk->alignmask = crypto_ablkcipher_alignmask(tfm);
+       return blkcipher_walk_first(desc, walk);
+}
+EXPORT_SYMBOL_GPL(blkcipher_ablkcipher_walk_virt);
+
 static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key,
                            unsigned int keylen)
 {
index c9fe145f7dd3bad3af8cd7902accefbc8c7b5366..04661e1fb6253e99f719a45aca4275525ba87826 100644 (file)
@@ -202,6 +202,9 @@ int blkcipher_aead_walk_virt_block(struct blkcipher_desc *desc,
                                   struct blkcipher_walk *walk,
                                   struct crypto_aead *tfm,
                                   unsigned int blocksize);
+int blkcipher_ablkcipher_walk_virt(struct blkcipher_desc *desc,
+                                  struct blkcipher_walk *walk,
+                                  struct crypto_ablkcipher *tfm);
 
 int ablkcipher_walk_done(struct ablkcipher_request *req,
                         struct ablkcipher_walk *walk, int err);