diff options
Diffstat (limited to 'target/linux/generic/backport-5.4/080-wireguard-0015-crypto-poly1305-expose-init-update-final-library-int.patch')
-rw-r--r-- | target/linux/generic/backport-5.4/080-wireguard-0015-crypto-poly1305-expose-init-update-final-library-int.patch | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/target/linux/generic/backport-5.4/080-wireguard-0015-crypto-poly1305-expose-init-update-final-library-int.patch b/target/linux/generic/backport-5.4/080-wireguard-0015-crypto-poly1305-expose-init-update-final-library-int.patch new file mode 100644 index 0000000000..bf8e90bf02 --- /dev/null +++ b/target/linux/generic/backport-5.4/080-wireguard-0015-crypto-poly1305-expose-init-update-final-library-int.patch @@ -0,0 +1,224 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel <ardb@kernel.org> +Date: Fri, 8 Nov 2019 13:22:21 +0100 +Subject: [PATCH] crypto: poly1305 - expose init/update/final library interface + +commit a1d93064094cc5e24d64e35cf093e7191d0c9344 upstream. + +Expose the existing generic Poly1305 code via a init/update/final +library interface so that callers are not required to go through +the crypto API's shash abstraction to access it. At the same time, +make some preparations so that the library implementation can be +superseded by an accelerated arch-specific version in the future. + +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> +--- + crypto/poly1305_generic.c | 22 +----------- + include/crypto/poly1305.h | 38 +++++++++++++++++++- + lib/crypto/Kconfig | 26 ++++++++++++++ + lib/crypto/poly1305.c | 74 +++++++++++++++++++++++++++++++++++++++ + 4 files changed, 138 insertions(+), 22 deletions(-) + +--- a/crypto/poly1305_generic.c ++++ b/crypto/poly1305_generic.c +@@ -85,31 +85,11 @@ EXPORT_SYMBOL_GPL(crypto_poly1305_update + int crypto_poly1305_final(struct shash_desc *desc, u8 *dst) + { + struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc); +- __le32 digest[4]; +- u64 f = 0; + + if (unlikely(!dctx->sset)) + return -ENOKEY; + +- if (unlikely(dctx->buflen)) { +- dctx->buf[dctx->buflen++] = 1; +- memset(dctx->buf + dctx->buflen, 0, +- POLY1305_BLOCK_SIZE - dctx->buflen); +- poly1305_core_blocks(&dctx->h, dctx->r, dctx->buf, 1, 0); +- } +- +- poly1305_core_emit(&dctx->h, digest); +- +- /* mac = (h + s) % (2^128) */ +- f = (f >> 32) + le32_to_cpu(digest[0]) + dctx->s[0]; +- put_unaligned_le32(f, dst + 0); +- f = (f >> 32) + le32_to_cpu(digest[1]) + dctx->s[1]; +- put_unaligned_le32(f, dst + 4); +- f = (f >> 32) + le32_to_cpu(digest[2]) + dctx->s[2]; +- put_unaligned_le32(f, dst + 8); +- f = (f >> 32) + le32_to_cpu(digest[3]) + dctx->s[3]; +- put_unaligned_le32(f, dst + 12); +- ++ poly1305_final_generic(dctx, dst); + return 0; + } + EXPORT_SYMBOL_GPL(crypto_poly1305_final); +--- a/include/crypto/poly1305.h ++++ b/include/crypto/poly1305.h +@@ -35,7 +35,43 @@ struct poly1305_desc_ctx { + /* accumulator */ + struct poly1305_state h; + /* key */ +- struct poly1305_key r[1]; ++ struct poly1305_key r[CONFIG_CRYPTO_LIB_POLY1305_RSIZE]; + }; + ++void poly1305_init_arch(struct poly1305_desc_ctx *desc, const u8 *key); ++void poly1305_init_generic(struct poly1305_desc_ctx *desc, const u8 *key); ++ ++static inline void poly1305_init(struct poly1305_desc_ctx *desc, const u8 *key) ++{ ++ if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305)) ++ poly1305_init_arch(desc, key); ++ else ++ poly1305_init_generic(desc, key); ++} ++ ++void poly1305_update_arch(struct poly1305_desc_ctx *desc, const u8 *src, ++ unsigned int nbytes); ++void poly1305_update_generic(struct poly1305_desc_ctx *desc, const u8 *src, ++ unsigned int nbytes); ++ ++static inline void poly1305_update(struct poly1305_desc_ctx *desc, ++ const u8 *src, unsigned int nbytes) ++{ ++ if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305)) ++ poly1305_update_arch(desc, src, nbytes); ++ else ++ poly1305_update_generic(desc, src, nbytes); ++} ++ ++void poly1305_final_arch(struct poly1305_desc_ctx *desc, u8 *digest); ++void poly1305_final_generic(struct poly1305_desc_ctx *desc, u8 *digest); ++ ++static inline void poly1305_final(struct poly1305_desc_ctx *desc, u8 *digest) ++{ ++ if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305)) ++ poly1305_final_arch(desc, digest); ++ else ++ poly1305_final_generic(desc, digest); ++} ++ + #endif +--- a/lib/crypto/Kconfig ++++ b/lib/crypto/Kconfig +@@ -37,8 +37,34 @@ config CRYPTO_LIB_CHACHA + config CRYPTO_LIB_DES + tristate + ++config CRYPTO_LIB_POLY1305_RSIZE ++ int ++ default 1 ++ ++config CRYPTO_ARCH_HAVE_LIB_POLY1305 ++ tristate ++ help ++ Declares whether the architecture provides an arch-specific ++ accelerated implementation of the Poly1305 library interface, ++ either builtin or as a module. ++ + config CRYPTO_LIB_POLY1305_GENERIC + tristate ++ help ++ This symbol can be depended upon by arch implementations of the ++ Poly1305 library interface that require the generic code as a ++ fallback, e.g., for SIMD implementations. If no arch specific ++ implementation is enabled, this implementation serves the users ++ of CRYPTO_LIB_POLY1305. ++ ++config CRYPTO_LIB_POLY1305 ++ tristate "Poly1305 library interface" ++ depends on CRYPTO_ARCH_HAVE_LIB_POLY1305 || !CRYPTO_ARCH_HAVE_LIB_POLY1305 ++ select CRYPTO_LIB_POLY1305_GENERIC if CRYPTO_ARCH_HAVE_LIB_POLY1305=n ++ help ++ Enable the Poly1305 library interface. This interface may be fulfilled ++ by either the generic implementation or an arch-specific one, if one ++ is available and enabled. + + config CRYPTO_LIB_SHA256 + tristate +--- a/lib/crypto/poly1305.c ++++ b/lib/crypto/poly1305.c +@@ -154,5 +154,79 @@ void poly1305_core_emit(const struct pol + } + EXPORT_SYMBOL_GPL(poly1305_core_emit); + ++void poly1305_init_generic(struct poly1305_desc_ctx *desc, const u8 *key) ++{ ++ poly1305_core_setkey(desc->r, key); ++ desc->s[0] = get_unaligned_le32(key + 16); ++ desc->s[1] = get_unaligned_le32(key + 20); ++ desc->s[2] = get_unaligned_le32(key + 24); ++ desc->s[3] = get_unaligned_le32(key + 28); ++ poly1305_core_init(&desc->h); ++ desc->buflen = 0; ++ desc->sset = true; ++ desc->rset = 1; ++} ++EXPORT_SYMBOL_GPL(poly1305_init_generic); ++ ++void poly1305_update_generic(struct poly1305_desc_ctx *desc, const u8 *src, ++ unsigned int nbytes) ++{ ++ unsigned int bytes; ++ ++ if (unlikely(desc->buflen)) { ++ bytes = min(nbytes, POLY1305_BLOCK_SIZE - desc->buflen); ++ memcpy(desc->buf + desc->buflen, src, bytes); ++ src += bytes; ++ nbytes -= bytes; ++ desc->buflen += bytes; ++ ++ if (desc->buflen == POLY1305_BLOCK_SIZE) { ++ poly1305_core_blocks(&desc->h, desc->r, desc->buf, 1, 1); ++ desc->buflen = 0; ++ } ++ } ++ ++ if (likely(nbytes >= POLY1305_BLOCK_SIZE)) { ++ poly1305_core_blocks(&desc->h, desc->r, src, ++ nbytes / POLY1305_BLOCK_SIZE, 1); ++ src += nbytes - (nbytes % POLY1305_BLOCK_SIZE); ++ nbytes %= POLY1305_BLOCK_SIZE; ++ } ++ ++ if (unlikely(nbytes)) { ++ desc->buflen = nbytes; ++ memcpy(desc->buf, src, nbytes); ++ } ++} ++EXPORT_SYMBOL_GPL(poly1305_update_generic); ++ ++void poly1305_final_generic(struct poly1305_desc_ctx *desc, u8 *dst) ++{ ++ __le32 digest[4]; ++ u64 f = 0; ++ ++ if (unlikely(desc->buflen)) { ++ desc->buf[desc->buflen++] = 1; ++ memset(desc->buf + desc->buflen, 0, ++ POLY1305_BLOCK_SIZE - desc->buflen); ++ poly1305_core_blocks(&desc->h, desc->r, desc->buf, 1, 0); ++ } ++ ++ poly1305_core_emit(&desc->h, digest); ++ ++ /* mac = (h + s) % (2^128) */ ++ f = (f >> 32) + le32_to_cpu(digest[0]) + desc->s[0]; ++ put_unaligned_le32(f, dst + 0); ++ f = (f >> 32) + le32_to_cpu(digest[1]) + desc->s[1]; ++ put_unaligned_le32(f, dst + 4); ++ f = (f >> 32) + le32_to_cpu(digest[2]) + desc->s[2]; ++ put_unaligned_le32(f, dst + 8); ++ f = (f >> 32) + le32_to_cpu(digest[3]) + desc->s[3]; ++ put_unaligned_le32(f, dst + 12); ++ ++ *desc = (struct poly1305_desc_ctx){}; ++} ++EXPORT_SYMBOL_GPL(poly1305_final_generic); ++ + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Martin Willi <martin@strongswan.org>"); |