crypto: algapi - use separate dst and src operands for __crypto_xor()
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Mon, 24 Jul 2017 10:28:03 +0000 (11:28 +0100)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 4 Aug 2017 01:27:05 +0000 (09:27 +0800)
In preparation of introducing crypto_xor_cpy(), which will use separate
operands for input and output, modify the __crypto_xor() implementation,
which it will share with the existing crypto_xor(), which provides the
actual functionality when not using the inline version.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
crypto/algapi.c
include/crypto/algapi.h

index e4cc7615a13954e581f020c7937eeec099102a26..aa699ff6c876565c0f716e39597edaa15ba9a6d8 100644 (file)
@@ -975,13 +975,15 @@ void crypto_inc(u8 *a, unsigned int size)
 }
 EXPORT_SYMBOL_GPL(crypto_inc);
 
-void __crypto_xor(u8 *dst, const u8 *src, unsigned int len)
+void __crypto_xor(u8 *dst, const u8 *src1, const u8 *src2, unsigned int len)
 {
        int relalign = 0;
 
        if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
                int size = sizeof(unsigned long);
-               int d = ((unsigned long)dst ^ (unsigned long)src) & (size - 1);
+               int d = (((unsigned long)dst ^ (unsigned long)src1) |
+                        ((unsigned long)dst ^ (unsigned long)src2)) &
+                       (size - 1);
 
                relalign = d ? 1 << __ffs(d) : size;
 
@@ -992,34 +994,37 @@ void __crypto_xor(u8 *dst, const u8 *src, unsigned int len)
                 * process the remainder of the input using optimal strides.
                 */
                while (((unsigned long)dst & (relalign - 1)) && len > 0) {
-                       *dst++ ^= *src++;
+                       *dst++ = *src1++ ^ *src2++;
                        len--;
                }
        }
 
        while (IS_ENABLED(CONFIG_64BIT) && len >= 8 && !(relalign & 7)) {
-               *(u64 *)dst ^= *(u64 *)src;
+               *(u64 *)dst = *(u64 *)src1 ^  *(u64 *)src2;
                dst += 8;
-               src += 8;
+               src1 += 8;
+               src2 += 8;
                len -= 8;
        }
 
        while (len >= 4 && !(relalign & 3)) {
-               *(u32 *)dst ^= *(u32 *)src;
+               *(u32 *)dst = *(u32 *)src1 ^ *(u32 *)src2;
                dst += 4;
-               src += 4;
+               src1 += 4;
+               src2 += 4;
                len -= 4;
        }
 
        while (len >= 2 && !(relalign & 1)) {
-               *(u16 *)dst ^= *(u16 *)src;
+               *(u16 *)dst = *(u16 *)src1 ^ *(u16 *)src2;
                dst += 2;
-               src += 2;
+               src1 += 2;
+               src2 += 2;
                len -= 2;
        }
 
        while (len--)
-               *dst++ ^= *src++;
+               *dst++ = *src1++ ^ *src2++;
 }
 EXPORT_SYMBOL_GPL(__crypto_xor);
 
index 436c4c2683c7dc81921cb029178967bf0e665abd..fd547f946bf8e0ada50ce9d1d9af98dbd29346dc 100644 (file)
@@ -192,7 +192,7 @@ static inline unsigned int crypto_queue_len(struct crypto_queue *queue)
 }
 
 void crypto_inc(u8 *a, unsigned int size);
-void __crypto_xor(u8 *dst, const u8 *src, unsigned int size);
+void __crypto_xor(u8 *dst, const u8 *src1, const u8 *src2, unsigned int size);
 
 static inline void crypto_xor(u8 *dst, const u8 *src, unsigned int size)
 {
@@ -207,7 +207,7 @@ static inline void crypto_xor(u8 *dst, const u8 *src, unsigned int size)
                        size -= sizeof(unsigned long);
                }
        } else {
-               __crypto_xor(dst, src, size);
+               __crypto_xor(dst, dst, src, size);
        }
 }