return 0;
 }
 
-static inline void inc(be128 *iv)
-{
-       be64_add_cpu(&iv->b, 1);
-       if (!iv->b)
-               be64_add_cpu(&iv->a, 1);
-}
-
-/* this returns the number of consequative 1 bits starting
- * from the right, get_index128(00 00 00 00 00 00 ... 00 00 10 FB) = 2 */
-static inline int get_index128(be128 *block)
+/*
+ * Returns the number of trailing '1' bits in the words of the counter, which is
+ * represented by 4 32-bit words, arranged from least to most significant.
+ * At the same time, increments the counter by one.
+ *
+ * For example:
+ *
+ * u32 counter[4] = { 0xFFFFFFFF, 0x1, 0x0, 0x0 };
+ * int i = next_index(&counter);
+ * // i == 33, counter == { 0x0, 0x2, 0x0, 0x0 }
+ */
+static int next_index(u32 *counter)
 {
-       int x;
-       __be32 *p = (__be32 *) block;
+       int i, res = 0;
 
-       for (p += 3, x = 0; x < 128; p--, x += 32) {
-               u32 val = be32_to_cpup(p);
-
-               if (!~val)
-                       continue;
-
-               return x + ffz(val);
+       for (i = 0; i < 4; i++) {
+               if (counter[i] + 1 != 0) {
+                       res += ffz(counter[i]++);
+                       break;
+               }
+               counter[i] = 0;
+               res += 32;
        }
 
        /*
        struct scatterlist *sg;
        unsigned cryptlen;
        unsigned offset;
-       be128 *iv;
        bool more;
+       __be32 *iv;
+       u32 counter[4];
        int err;
 
        subreq = &rctx->subreq;
                                   cryptlen, req->iv);
 
        err = skcipher_walk_virt(&w, subreq, false);
-       iv = w.iv;
+       iv = (__be32 *)w.iv;
+
+       counter[0] = be32_to_cpu(iv[3]);
+       counter[1] = be32_to_cpu(iv[2]);
+       counter[2] = be32_to_cpu(iv[1]);
+       counter[3] = be32_to_cpu(iv[0]);
 
        while (w.nbytes) {
                unsigned int avail = w.nbytes;
                        /* T <- I*Key2, using the optimization
                         * discussed in the specification */
                        be128_xor(&rctx->t, &rctx->t,
-                                 &ctx->mulinc[get_index128(iv)]);
-                       inc(iv);
+                                 &ctx->mulinc[next_index(counter)]);
                } while ((avail -= bs) >= bs);
 
+               if (w.nbytes == w.total) {
+                       iv[0] = cpu_to_be32(counter[3]);
+                       iv[1] = cpu_to_be32(counter[2]);
+                       iv[2] = cpu_to_be32(counter[1]);
+                       iv[3] = cpu_to_be32(counter[0]);
+               }
+
                err = skcipher_walk_done(&w, avail);
        }
 
        inst->alg.base.cra_priority = alg->base.cra_priority;
        inst->alg.base.cra_blocksize = LRW_BLOCK_SIZE;
        inst->alg.base.cra_alignmask = alg->base.cra_alignmask |
-                                      (__alignof__(u64) - 1);
+                                      (__alignof__(__be32) - 1);
 
        inst->alg.ivsize = LRW_BLOCK_SIZE;
        inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(alg) +