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 |
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
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
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.
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
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,
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
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,
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 --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");