diff mbox series

[v3,2/3] crypto: lib - move __crypto_xor into utils

Message ID 20220725183636.97326-3-ebiggers@kernel.org (mailing list archive)
State Accepted
Delegated to: Herbert Xu
Headers show
Series crypto: lib - create utils module | expand

Commit Message

Eric Biggers July 25, 2022, 6:36 p.m. UTC
From: Eric Biggers <ebiggers@google.com>

CRYPTO_LIB_CHACHA depends on CRYPTO for __crypto_xor, defined in
crypto/algapi.c.  This is a layering violation because the dependencies
should only go in the other direction (crypto/ => lib/crypto/).  Also
the correct dependency would be CRYPTO_ALGAPI, not CRYPTO.  Fix this by
moving __crypto_xor into the utils module in lib/crypto/.

Note that CRYPTO_LIB_CHACHA_GENERIC selected XOR_BLOCKS, which is
unrelated and unnecessary.  It was perhaps thought that XOR_BLOCKS was
needed for __crypto_xor, but that's not the case.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 crypto/algapi.c     | 71 ------------------------------------
 lib/crypto/Kconfig  |  3 +-
 lib/crypto/Makefile |  2 +-
 lib/crypto/memneq.c |  2 --
 lib/crypto/utils.c  | 88 +++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 90 insertions(+), 76 deletions(-)
 create mode 100644 lib/crypto/utils.c

Comments

Jason A. Donenfeld July 25, 2022, 10:09 p.m. UTC | #1
On Mon, Jul 25, 2022 at 11:36:35AM -0700, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> CRYPTO_LIB_CHACHA depends on CRYPTO for __crypto_xor, defined in
> crypto/algapi.c.  This is a layering violation because the dependencies
> should only go in the other direction (crypto/ => lib/crypto/).  Also
> the correct dependency would be CRYPTO_ALGAPI, not CRYPTO.  Fix this by
> moving __crypto_xor into the utils module in lib/crypto/.
> 
> Note that CRYPTO_LIB_CHACHA_GENERIC selected XOR_BLOCKS, which is
> unrelated and unnecessary.  It was perhaps thought that XOR_BLOCKS was
> needed for __crypto_xor, but that's not the case.
> 
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>

With one small question:

> --- /dev/null
> +++ b/lib/crypto/utils.c
> @@ -0,0 +1,88 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Crypto library utility functions
> + *
> + * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>

Didn't Ard basically write the crypto_xor function in its current form?
I seem to remember some pretty hardcore refactoring he did a while back.

Jason
Eric Biggers July 26, 2022, 1 a.m. UTC | #2
On Tue, Jul 26, 2022 at 12:09:33AM +0200, Jason A. Donenfeld wrote:
> On Mon, Jul 25, 2022 at 11:36:35AM -0700, Eric Biggers wrote:
> > From: Eric Biggers <ebiggers@google.com>
> > 
> > CRYPTO_LIB_CHACHA depends on CRYPTO for __crypto_xor, defined in
> > crypto/algapi.c.  This is a layering violation because the dependencies
> > should only go in the other direction (crypto/ => lib/crypto/).  Also
> > the correct dependency would be CRYPTO_ALGAPI, not CRYPTO.  Fix this by
> > moving __crypto_xor into the utils module in lib/crypto/.
> > 
> > Note that CRYPTO_LIB_CHACHA_GENERIC selected XOR_BLOCKS, which is
> > unrelated and unnecessary.  It was perhaps thought that XOR_BLOCKS was
> > needed for __crypto_xor, but that's not the case.
> > 
> > Signed-off-by: Eric Biggers <ebiggers@google.com>
> 
> Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
> 
> With one small question:
> 
> > --- /dev/null
> > +++ b/lib/crypto/utils.c
> > @@ -0,0 +1,88 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Crypto library utility functions
> > + *
> > + * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
> 
> Didn't Ard basically write the crypto_xor function in its current form?
> I seem to remember some pretty hardcore refactoring he did a while back.
> 
> Jason

I think that's fair to say, based on git blame.  I just copied the copyright
statement from the top of crypto/algapi.c.

- Eric
Ard Biesheuvel July 26, 2022, 1:46 p.m. UTC | #3
On Mon, 25 Jul 2022 at 15:09, Jason A. Donenfeld <Jason@zx2c4.com> wrote:
>
> On Mon, Jul 25, 2022 at 11:36:35AM -0700, Eric Biggers wrote:
> > From: Eric Biggers <ebiggers@google.com>
> >
> > CRYPTO_LIB_CHACHA depends on CRYPTO for __crypto_xor, defined in
> > crypto/algapi.c.  This is a layering violation because the dependencies
> > should only go in the other direction (crypto/ => lib/crypto/).  Also
> > the correct dependency would be CRYPTO_ALGAPI, not CRYPTO.  Fix this by
> > moving __crypto_xor into the utils module in lib/crypto/.
> >
> > Note that CRYPTO_LIB_CHACHA_GENERIC selected XOR_BLOCKS, which is
> > unrelated and unnecessary.  It was perhaps thought that XOR_BLOCKS was
> > needed for __crypto_xor, but that's not the case.
> >
> > Signed-off-by: Eric Biggers <ebiggers@google.com>
>
> Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
>
> With one small question:
>
> > --- /dev/null
> > +++ b/lib/crypto/utils.c
> > @@ -0,0 +1,88 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Crypto library utility functions
> > + *
> > + * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
>
> Didn't Ard basically write the crypto_xor function in its current form?
> I seem to remember some pretty hardcore refactoring he did a while back.
>

Hi Jason,

Thanks for pointing this out. When I made those changes, I don't think
an authorship assertion for copyright purposes was appropriate for the
entire .c file (the FSF have some guidelines for this IIRC). It would
also be strange for me or Eric to suddenly introduce a (c) Linaro (or
ARM, not sure who my employer was at the time) at this point, so I
think we can just leave this as proposed by Eric.
Eric Biggers Aug. 26, 2022, 4:44 a.m. UTC | #4
Herbert, Jason, and Justin:

On Mon, Jul 25, 2022 at 11:36:35AM -0700, Eric Biggers wrote:
> diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig
> index b09d9d6546cbc3..7e9683e9f5c636 100644
> --- a/lib/crypto/Kconfig
> +++ b/lib/crypto/Kconfig
> @@ -36,7 +36,7 @@ config CRYPTO_ARCH_HAVE_LIB_CHACHA
>  
>  config CRYPTO_LIB_CHACHA_GENERIC
>  	tristate
> -	select XOR_BLOCKS
> +	select CRYPTO_LIB_UTILS
>  	help
>  	  This symbol can be depended upon by arch implementations of the
>  	  ChaCha library interface that require the generic code as a

Just a heads up; the unnecessary selection of XOR_BLOCKS here (which got
backported to v5.10.120 and v5.15.45 by "lib/crypto: add prompts back to crypto
libraries") can be considered an actual bug, as it increases boot time on
systems that didn't have it selected before.  This is because the code enabled
by XOR_BLOCKS (crypto/xor.c) runs a benchmark, which takes some time.  It
doesn't take *that* long, but it got noticed as a regression nonetheless, and it
needs to be fixed.  My patch series happens to have fixed this, but I didn't
have it mind that it was a real bug fix.

Herbert, any chance that you could send my patch series to Linus without waiting
for the next merge window, so that it can be backported?

- Eric
Herbert Xu Aug. 26, 2022, 4:46 a.m. UTC | #5
On Thu, Aug 25, 2022 at 09:44:38PM -0700, Eric Biggers wrote:
.
> Herbert, any chance that you could send my patch series to Linus without waiting
> for the next merge window, so that it can be backported?

Sure, which patch fixes this?

Cheers,
Eric Biggers Aug. 26, 2022, 4:48 a.m. UTC | #6
On Fri, Aug 26, 2022 at 12:46:25PM +0800, Herbert Xu wrote:
> On Thu, Aug 25, 2022 at 09:44:38PM -0700, Eric Biggers wrote:
> .
> > Herbert, any chance that you could send my patch series to Linus without waiting
> > for the next merge window, so that it can be backported?
> 
> Sure, which patch fixes this?
> 

The one I'm commenting on (patch 2 of 3).  But patch 1 is needed as a
prerequisite.

- Eric
Herbert Xu Aug. 26, 2022, 4:52 a.m. UTC | #7
On Thu, Aug 25, 2022 at 09:48:25PM -0700, Eric Biggers wrote:
>
> The one I'm commenting on (patch 2 of 3).  But patch 1 is needed as a
> prerequisite.

Oh so it's just dropping the select? Can you please send me a
separate patch for the crypto tree with a Fixes header? I'll
deal with the merge conflict.

Thanks,
Eric Biggers Aug. 26, 2022, 5:07 a.m. UTC | #8
On Fri, Aug 26, 2022 at 12:52:53PM +0800, Herbert Xu wrote:
> On Thu, Aug 25, 2022 at 09:48:25PM -0700, Eric Biggers wrote:
> >
> > The one I'm commenting on (patch 2 of 3).  But patch 1 is needed as a
> > prerequisite.
> 
> Oh so it's just dropping the select? Can you please send me a
> separate patch for the crypto tree with a Fixes header? I'll
> deal with the merge conflict.
> 

Done: https://lore.kernel.org/r/20220826050456.101321-1-ebiggers@kernel.org

- Eric
diff mbox series

Patch

diff --git a/crypto/algapi.c b/crypto/algapi.c
index d1c99288af3e0d..5c69ff8e8fa5c1 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -997,77 +997,6 @@  void crypto_inc(u8 *a, unsigned int size)
 }
 EXPORT_SYMBOL_GPL(crypto_inc);
 
-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)src1) |
-			 ((unsigned long)dst ^ (unsigned long)src2)) &
-			(size - 1);
-
-		relalign = d ? 1 << __ffs(d) : size;
-
-		/*
-		 * If we care about alignment, process as many bytes as
-		 * needed to advance dst and src to values whose alignments
-		 * equal their relative alignment. This will allow us to
-		 * process the remainder of the input using optimal strides.
-		 */
-		while (((unsigned long)dst & (relalign - 1)) && len > 0) {
-			*dst++ = *src1++ ^ *src2++;
-			len--;
-		}
-	}
-
-	while (IS_ENABLED(CONFIG_64BIT) && len >= 8 && !(relalign & 7)) {
-		if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
-			u64 l = get_unaligned((u64 *)src1) ^
-				get_unaligned((u64 *)src2);
-			put_unaligned(l, (u64 *)dst);
-		} else {
-			*(u64 *)dst = *(u64 *)src1 ^ *(u64 *)src2;
-		}
-		dst += 8;
-		src1 += 8;
-		src2 += 8;
-		len -= 8;
-	}
-
-	while (len >= 4 && !(relalign & 3)) {
-		if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
-			u32 l = get_unaligned((u32 *)src1) ^
-				get_unaligned((u32 *)src2);
-			put_unaligned(l, (u32 *)dst);
-		} else {
-			*(u32 *)dst = *(u32 *)src1 ^ *(u32 *)src2;
-		}
-		dst += 4;
-		src1 += 4;
-		src2 += 4;
-		len -= 4;
-	}
-
-	while (len >= 2 && !(relalign & 1)) {
-		if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
-			u16 l = get_unaligned((u16 *)src1) ^
-				get_unaligned((u16 *)src2);
-			put_unaligned(l, (u16 *)dst);
-		} else {
-			*(u16 *)dst = *(u16 *)src1 ^ *(u16 *)src2;
-		}
-		dst += 2;
-		src1 += 2;
-		src2 += 2;
-		len -= 2;
-	}
-
-	while (len--)
-		*dst++ = *src1++ ^ *src2++;
-}
-EXPORT_SYMBOL_GPL(__crypto_xor);
-
 unsigned int crypto_alg_extsize(struct crypto_alg *alg)
 {
 	return alg->cra_ctxsize +
diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig
index b09d9d6546cbc3..7e9683e9f5c636 100644
--- a/lib/crypto/Kconfig
+++ b/lib/crypto/Kconfig
@@ -36,7 +36,7 @@  config CRYPTO_ARCH_HAVE_LIB_CHACHA
 
 config CRYPTO_LIB_CHACHA_GENERIC
 	tristate
-	select XOR_BLOCKS
+	select CRYPTO_LIB_UTILS
 	help
 	  This symbol can be depended upon by arch implementations of the
 	  ChaCha library interface that require the generic code as a
@@ -46,7 +46,6 @@  config CRYPTO_LIB_CHACHA_GENERIC
 
 config CRYPTO_LIB_CHACHA
 	tristate "ChaCha library interface"
-	depends on CRYPTO
 	depends on CRYPTO_ARCH_HAVE_LIB_CHACHA || !CRYPTO_ARCH_HAVE_LIB_CHACHA
 	select CRYPTO_LIB_CHACHA_GENERIC if CRYPTO_ARCH_HAVE_LIB_CHACHA=n
 	help
diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile
index b956b3bae26aaf..c852f067ab0601 100644
--- a/lib/crypto/Makefile
+++ b/lib/crypto/Makefile
@@ -1,7 +1,7 @@ 
 # SPDX-License-Identifier: GPL-2.0
 
 obj-$(CONFIG_CRYPTO_LIB_UTILS)			+= libcryptoutils.o
-libcryptoutils-y				:= memneq.o
+libcryptoutils-y				:= memneq.o utils.o
 
 # chacha is used by the /dev/random driver which is always builtin
 obj-y						+= chacha.o
diff --git a/lib/crypto/memneq.c b/lib/crypto/memneq.c
index f2098318428478..d1e8c86fbb0fcf 100644
--- a/lib/crypto/memneq.c
+++ b/lib/crypto/memneq.c
@@ -175,5 +175,3 @@  noinline unsigned long __crypto_memneq(const void *a, const void *b,
 EXPORT_SYMBOL(__crypto_memneq);
 
 #endif /* __HAVE_ARCH_CRYPTO_MEMNEQ */
-
-MODULE_LICENSE("GPL");
diff --git a/lib/crypto/utils.c b/lib/crypto/utils.c
new file mode 100644
index 00000000000000..53230ab1b19576
--- /dev/null
+++ b/lib/crypto/utils.c
@@ -0,0 +1,88 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Crypto library utility functions
+ *
+ * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
+ */
+
+#include <asm/unaligned.h>
+#include <crypto/algapi.h>
+#include <linux/module.h>
+
+/*
+ * XOR @len bytes from @src1 and @src2 together, writing the result to @dst
+ * (which may alias one of the sources).  Don't call this directly; call
+ * crypto_xor() or crypto_xor_cpy() instead.
+ */
+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)src1) |
+			 ((unsigned long)dst ^ (unsigned long)src2)) &
+			(size - 1);
+
+		relalign = d ? 1 << __ffs(d) : size;
+
+		/*
+		 * If we care about alignment, process as many bytes as
+		 * needed to advance dst and src to values whose alignments
+		 * equal their relative alignment. This will allow us to
+		 * process the remainder of the input using optimal strides.
+		 */
+		while (((unsigned long)dst & (relalign - 1)) && len > 0) {
+			*dst++ = *src1++ ^ *src2++;
+			len--;
+		}
+	}
+
+	while (IS_ENABLED(CONFIG_64BIT) && len >= 8 && !(relalign & 7)) {
+		if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
+			u64 l = get_unaligned((u64 *)src1) ^
+				get_unaligned((u64 *)src2);
+			put_unaligned(l, (u64 *)dst);
+		} else {
+			*(u64 *)dst = *(u64 *)src1 ^ *(u64 *)src2;
+		}
+		dst += 8;
+		src1 += 8;
+		src2 += 8;
+		len -= 8;
+	}
+
+	while (len >= 4 && !(relalign & 3)) {
+		if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
+			u32 l = get_unaligned((u32 *)src1) ^
+				get_unaligned((u32 *)src2);
+			put_unaligned(l, (u32 *)dst);
+		} else {
+			*(u32 *)dst = *(u32 *)src1 ^ *(u32 *)src2;
+		}
+		dst += 4;
+		src1 += 4;
+		src2 += 4;
+		len -= 4;
+	}
+
+	while (len >= 2 && !(relalign & 1)) {
+		if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
+			u16 l = get_unaligned((u16 *)src1) ^
+				get_unaligned((u16 *)src2);
+			put_unaligned(l, (u16 *)dst);
+		} else {
+			*(u16 *)dst = *(u16 *)src1 ^ *(u16 *)src2;
+		}
+		dst += 2;
+		src1 += 2;
+		src2 += 2;
+		len -= 2;
+	}
+
+	while (len--)
+		*dst++ = *src1++ ^ *src2++;
+}
+EXPORT_SYMBOL_GPL(__crypto_xor);
+
+MODULE_LICENSE("GPL");