lib/crypto: powerpc/poly1305: Remove BROKEN implementation

The PowerPC implementation of Poly1305 has been marked as BROKEN for
well over a year, since commit bc8169003b ("crypto: powerpc/poly1305 -
add depends on BROKEN for now").  So, it's not being built or used.

The justification for marking it BROKEN was that it didn't work in
softirq context.  That still fully applies.

However, it turns out the assembly file actually also contains logic
bugs that make it compute incorrect Poly1305 values in some cases.  This
is shown by it failing the test case test_poly1305_split_update_carry
(if "depends on BROKEN" is removed).  The cause of that appears to be a
lost carry bit in Carry_reduction.  However, there also appears to be a
bug in do_final_update where it incorrectly assumes v6 is fully reduced.

In addition, poly1305_emit_64 contains a secret-dependent branch.

Let's just drop this code.  A fixed version can be reconsidered later.

Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://patch.msgid.link/20261029063522.124421-1-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
This commit is contained in:
Eric Biggers 2026-10-28 23:35:21 -07:00
parent dd2a4edb26
commit 539436435f
4 changed files with 1 additions and 1159 deletions

View File

@ -197,8 +197,6 @@ config CRYPTO_LIB_POLY1305_ARCH
default y if ARM
default y if ARM64
default y if MIPS
# The PPC64 code needs to be fixed to work in softirq context.
default y if PPC64 && CPU_LITTLE_ENDIAN && VSX && BROKEN
default y if RISCV
default y if X86_64
@ -209,9 +207,7 @@ config CRYPTO_LIB_POLY1305_ARCH
config CRYPTO_LIB_POLY1305_GENERIC
bool
depends on CRYPTO_LIB_POLY1305
# Enable if there's no arch impl or the arch impl requires the generic
# impl as a fallback. (Or if selected explicitly.)
default y if !CRYPTO_LIB_POLY1305_ARCH || PPC64
default y if !CRYPTO_LIB_POLY1305_ARCH
config CRYPTO_LIB_POLY1305_RSIZE
int

View File

@ -256,8 +256,6 @@ $(obj)/mips/poly1305-core.S: $(src)/mips/poly1305-mips.pl FORCE
targets += mips/poly1305-core.S
endif
libpoly1305-$(CONFIG_PPC) += powerpc/poly1305-p10le_64.o
ifeq ($(CONFIG_RISCV),y)
libpoly1305-y += riscv/poly1305-core.o
poly1305-perlasm-flavour-$(CONFIG_32BIT) := 32

File diff suppressed because it is too large Load Diff

View File

@ -1,76 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Poly1305 authenticator algorithm, RFC7539.
*
* Copyright 2023- IBM Corp. All rights reserved.
*/
#include <asm/switch_to.h>
#include <linux/cpufeature.h>
#include <linux/jump_label.h>
#include <linux/kernel.h>
#include <linux/unaligned.h>
asmlinkage void poly1305_p10le_4blocks(struct poly1305_block_state *state,
const u8 *m, size_t mlen);
asmlinkage void poly1305_64s(struct poly1305_block_state *state, const u8 *m,
size_t mlen, int highbit);
asmlinkage void poly1305_emit_64(const struct poly1305_state *state, const u32 nonce[4], u8 digest[POLY1305_DIGEST_SIZE]);
static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_p10);
static void vsx_begin(void)
{
preempt_disable();
enable_kernel_vsx();
}
static void vsx_end(void)
{
disable_kernel_vsx();
preempt_enable();
}
static void poly1305_block_init(struct poly1305_block_state *dctx,
const u8 raw_key[POLY1305_BLOCK_SIZE])
{
if (!static_key_enabled(&have_p10))
return poly1305_block_init_generic(dctx, raw_key);
dctx->h = (struct poly1305_state){};
dctx->core_r.key.r64[0] = get_unaligned_le64(raw_key + 0);
dctx->core_r.key.r64[1] = get_unaligned_le64(raw_key + 8);
}
static void poly1305_blocks(struct poly1305_block_state *state, const u8 *src,
size_t len, u32 padbit)
{
if (!static_key_enabled(&have_p10))
return poly1305_blocks_generic(state, src, len, padbit);
vsx_begin();
if (len >= POLY1305_BLOCK_SIZE * 4) {
poly1305_p10le_4blocks(state, src, len);
src += len - (len % (POLY1305_BLOCK_SIZE * 4));
len %= POLY1305_BLOCK_SIZE * 4;
}
while (len >= POLY1305_BLOCK_SIZE) {
poly1305_64s(state, src, POLY1305_BLOCK_SIZE, padbit);
len -= POLY1305_BLOCK_SIZE;
src += POLY1305_BLOCK_SIZE;
}
vsx_end();
}
static void poly1305_emit(const struct poly1305_state *state,
u8 digest[POLY1305_DIGEST_SIZE], const u32 nonce[4])
{
if (!static_key_enabled(&have_p10))
return poly1305_emit_generic(state, digest, nonce);
poly1305_emit_64(state, nonce, digest);
}
#define poly1305_mod_init_arch poly1305_mod_init_arch
static void poly1305_mod_init_arch(void)
{
if (cpu_has_feature(CPU_FTR_ARCH_31))
static_branch_enable(&have_p10);
}