diff options
Diffstat (limited to 'target/linux/generic/backport-5.4/080-wireguard-0016-crypto-x86-poly1305-depend-on-generic-library-not-ge.patch')
-rw-r--r-- | target/linux/generic/backport-5.4/080-wireguard-0016-crypto-x86-poly1305-depend-on-generic-library-not-ge.patch | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/target/linux/generic/backport-5.4/080-wireguard-0016-crypto-x86-poly1305-depend-on-generic-library-not-ge.patch b/target/linux/generic/backport-5.4/080-wireguard-0016-crypto-x86-poly1305-depend-on-generic-library-not-ge.patch new file mode 100644 index 0000000000..a1fe77cd5a --- /dev/null +++ b/target/linux/generic/backport-5.4/080-wireguard-0016-crypto-x86-poly1305-depend-on-generic-library-not-ge.patch @@ -0,0 +1,217 @@ +From 0e610172b19b8f7c1ce829247ce5f302b25ad100 Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel <ardb@kernel.org> +Date: Fri, 8 Nov 2019 13:22:22 +0100 +Subject: [PATCH 016/124] crypto: x86/poly1305 - depend on generic library not + generic shash + +commit 1b2c6a5120489d41c8ea3b8dacd0b4586289b158 upstream. + +Remove the dependency on the generic Poly1305 driver. Instead, depend +on the generic library so that we only reuse code without pulling in +the generic skcipher implementation as well. + +While at it, remove the logic that prefers the non-SIMD path for short +inputs - this is no longer necessary after recent FPU handling changes +on x86. + +Since this removes the last remaining user of the routines exported +by the generic shash driver, unexport them and make them static. + +Signed-off-by: Ard Biesheuvel <ardb@kernel.org> +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> +Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> +--- + arch/x86/crypto/poly1305_glue.c | 66 +++++++++++++++++++++++++----- + crypto/Kconfig | 2 +- + crypto/poly1305_generic.c | 11 ++--- + include/crypto/internal/poly1305.h | 9 ---- + 4 files changed, 60 insertions(+), 28 deletions(-) + +--- a/arch/x86/crypto/poly1305_glue.c ++++ b/arch/x86/crypto/poly1305_glue.c +@@ -34,6 +34,24 @@ static void poly1305_simd_mult(u32 *a, c + poly1305_block_sse2(a, m, b, 1); + } + ++static unsigned int poly1305_scalar_blocks(struct poly1305_desc_ctx *dctx, ++ const u8 *src, unsigned int srclen) ++{ ++ unsigned int datalen; ++ ++ if (unlikely(!dctx->sset)) { ++ datalen = crypto_poly1305_setdesckey(dctx, src, srclen); ++ src += srclen - datalen; ++ srclen = datalen; ++ } ++ if (srclen >= POLY1305_BLOCK_SIZE) { ++ poly1305_core_blocks(&dctx->h, dctx->r, src, ++ srclen / POLY1305_BLOCK_SIZE, 1); ++ srclen %= POLY1305_BLOCK_SIZE; ++ } ++ return srclen; ++} ++ + static unsigned int poly1305_simd_blocks(struct poly1305_desc_ctx *dctx, + const u8 *src, unsigned int srclen) + { +@@ -91,12 +109,6 @@ static int poly1305_simd_update(struct s + struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc); + unsigned int bytes; + +- /* kernel_fpu_begin/end is costly, use fallback for small updates */ +- if (srclen <= 288 || !crypto_simd_usable()) +- return crypto_poly1305_update(desc, src, srclen); +- +- kernel_fpu_begin(); +- + if (unlikely(dctx->buflen)) { + bytes = min(srclen, POLY1305_BLOCK_SIZE - dctx->buflen); + memcpy(dctx->buf + dctx->buflen, src, bytes); +@@ -105,25 +117,57 @@ static int poly1305_simd_update(struct s + dctx->buflen += bytes; + + if (dctx->buflen == POLY1305_BLOCK_SIZE) { +- poly1305_simd_blocks(dctx, dctx->buf, +- POLY1305_BLOCK_SIZE); ++ if (likely(crypto_simd_usable())) { ++ kernel_fpu_begin(); ++ poly1305_simd_blocks(dctx, dctx->buf, ++ POLY1305_BLOCK_SIZE); ++ kernel_fpu_end(); ++ } else { ++ poly1305_scalar_blocks(dctx, dctx->buf, ++ POLY1305_BLOCK_SIZE); ++ } + dctx->buflen = 0; + } + } + + if (likely(srclen >= POLY1305_BLOCK_SIZE)) { +- bytes = poly1305_simd_blocks(dctx, src, srclen); ++ if (likely(crypto_simd_usable())) { ++ kernel_fpu_begin(); ++ bytes = poly1305_simd_blocks(dctx, src, srclen); ++ kernel_fpu_end(); ++ } else { ++ bytes = poly1305_scalar_blocks(dctx, src, srclen); ++ } + src += srclen - bytes; + srclen = bytes; + } + +- kernel_fpu_end(); +- + if (unlikely(srclen)) { + dctx->buflen = srclen; + memcpy(dctx->buf, src, srclen); + } ++} ++ ++static int crypto_poly1305_init(struct shash_desc *desc) ++{ ++ struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc); ++ ++ poly1305_core_init(&dctx->h); ++ dctx->buflen = 0; ++ dctx->rset = 0; ++ dctx->sset = false; ++ ++ return 0; ++} ++ ++static int crypto_poly1305_final(struct shash_desc *desc, u8 *dst) ++{ ++ struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc); ++ ++ if (unlikely(!dctx->sset)) ++ return -ENOKEY; + ++ poly1305_final_generic(dctx, dst); + return 0; + } + +--- a/crypto/Kconfig ++++ b/crypto/Kconfig +@@ -697,7 +697,7 @@ config CRYPTO_POLY1305 + config CRYPTO_POLY1305_X86_64 + tristate "Poly1305 authenticator algorithm (x86_64/SSE2/AVX2)" + depends on X86 && 64BIT +- select CRYPTO_POLY1305 ++ select CRYPTO_LIB_POLY1305_GENERIC + help + Poly1305 authenticator algorithm, RFC7539. + +--- a/crypto/poly1305_generic.c ++++ b/crypto/poly1305_generic.c +@@ -19,7 +19,7 @@ + #include <linux/module.h> + #include <asm/unaligned.h> + +-int crypto_poly1305_init(struct shash_desc *desc) ++static int crypto_poly1305_init(struct shash_desc *desc) + { + struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc); + +@@ -30,7 +30,6 @@ int crypto_poly1305_init(struct shash_de + + return 0; + } +-EXPORT_SYMBOL_GPL(crypto_poly1305_init); + + static void poly1305_blocks(struct poly1305_desc_ctx *dctx, const u8 *src, + unsigned int srclen) +@@ -47,8 +46,8 @@ static void poly1305_blocks(struct poly1 + srclen / POLY1305_BLOCK_SIZE, 1); + } + +-int crypto_poly1305_update(struct shash_desc *desc, +- const u8 *src, unsigned int srclen) ++static int crypto_poly1305_update(struct shash_desc *desc, ++ const u8 *src, unsigned int srclen) + { + struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc); + unsigned int bytes; +@@ -80,9 +79,8 @@ int crypto_poly1305_update(struct shash_ + + return 0; + } +-EXPORT_SYMBOL_GPL(crypto_poly1305_update); + +-int crypto_poly1305_final(struct shash_desc *desc, u8 *dst) ++static int crypto_poly1305_final(struct shash_desc *desc, u8 *dst) + { + struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc); + +@@ -92,7 +90,6 @@ int crypto_poly1305_final(struct shash_d + poly1305_final_generic(dctx, dst); + return 0; + } +-EXPORT_SYMBOL_GPL(crypto_poly1305_final); + + static struct shash_alg poly1305_alg = { + .digestsize = POLY1305_DIGEST_SIZE, +--- a/include/crypto/internal/poly1305.h ++++ b/include/crypto/internal/poly1305.h +@@ -10,8 +10,6 @@ + #include <linux/types.h> + #include <crypto/poly1305.h> + +-struct shash_desc; +- + /* + * Poly1305 core functions. These implement the ε-almost-∆-universal hash + * function underlying the Poly1305 MAC, i.e. they don't add an encrypted nonce +@@ -28,13 +26,6 @@ void poly1305_core_blocks(struct poly130 + unsigned int nblocks, u32 hibit); + void poly1305_core_emit(const struct poly1305_state *state, void *dst); + +-/* Crypto API helper functions for the Poly1305 MAC */ +-int crypto_poly1305_init(struct shash_desc *desc); +- +-int crypto_poly1305_update(struct shash_desc *desc, +- const u8 *src, unsigned int srclen); +-int crypto_poly1305_final(struct shash_desc *desc, u8 *dst); +- + /* + * Poly1305 requires a unique key for each tag, which implies that we can't set + * it on the tfm that gets accessed by multiple users simultaneously. Instead we |