ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
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 0000000..bf8e90b
--- /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>");