* [PATCH] lib/crypto: poly1305: Hide the mask value from compilers
@ 2026-10-31 4:26 Eric Biggers
2026-11-02 9:16 ` Ard Biesheuvel
2026-11-03 23:26 ` Eric Biggers
0 siblings, 2 replies; 3+ messages in thread
From: Eric Biggers @ 2026-10-31 4:26 UTC (permalink / raw)
To: linux-crypto
Cc: Ard Biesheuvel, Jason A . Donenfeld, Herbert Xu, Eric Biggers
poly1305_core_emit() does a constant-time select between h and h - p,
where h is the accumulator and p is the Poly1305 prime of 2^130 - 5.
The mask used in this select isn't hidden from the compiler, though, so
the compiler can infer that it's either all 0's or all 1's.
In theory, the compiler could then use that to recognize the select, and
"optimize" it with a branch.
Fortunately, in practice, I couldn't find any gcc or clang options that
made that happen.
Regardless, add OPTIMIZER_HIDE_VAR() to "hide" the value of the mask for
safety against any future compiler optimizations.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
lib/crypto/poly1305-donna32.c | 1 +
lib/crypto/poly1305-donna64.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/lib/crypto/poly1305-donna32.c b/lib/crypto/poly1305-donna32.c
index 5977785cd76e..73fe9181296c 100644
--- a/lib/crypto/poly1305-donna32.c
+++ b/lib/crypto/poly1305-donna32.c
@@ -167,6 +167,7 @@ void poly1305_core_emit(const struct poly1305_state *state, const u32 nonce[4],
/* select h if h < p, or h + -p if h >= p */
mask = (g4 >> ((sizeof(u32) * 8) - 1)) - 1;
+ OPTIMIZER_HIDE_VAR(mask);
g0 &= mask;
g1 &= mask;
g2 &= mask;
diff --git a/lib/crypto/poly1305-donna64.c b/lib/crypto/poly1305-donna64.c
index d0e4234c1c4c..402a3459ca49 100644
--- a/lib/crypto/poly1305-donna64.c
+++ b/lib/crypto/poly1305-donna64.c
@@ -152,6 +152,7 @@ void poly1305_core_emit(const struct poly1305_state *state, const u32 nonce[4],
/* select h if h < p, or h + -p if h >= p */
c = (g2 >> ((sizeof(u64) * 8) - 1)) - 1;
+ OPTIMIZER_HIDE_VAR(c);
g0 &= c;
g1 &= c;
g2 &= c;
base-commit: 2a500a04d6f969318c05f46aedb6e73fc1963a00
--
2.56.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] lib/crypto: poly1305: Hide the mask value from compilers
2026-10-31 4:26 [PATCH] lib/crypto: poly1305: Hide the mask value from compilers Eric Biggers
@ 2026-11-02 9:16 ` Ard Biesheuvel
2026-11-03 23:26 ` Eric Biggers
1 sibling, 0 replies; 3+ messages in thread
From: Ard Biesheuvel @ 2026-11-02 9:16 UTC (permalink / raw)
To: Eric Biggers, linux-crypto; +Cc: Jason A . Donenfeld, Herbert Xu
On Sat, 31 Oct 2026, at 05:26, Eric Biggers wrote:
> poly1305_core_emit() does a constant-time select between h and h - p,
> where h is the accumulator and p is the Poly1305 prime of 2^130 - 5.
>
> The mask used in this select isn't hidden from the compiler, though, so
> the compiler can infer that it's either all 0's or all 1's.
>
> In theory, the compiler could then use that to recognize the select, and
> "optimize" it with a branch.
>
> Fortunately, in practice, I couldn't find any gcc or clang options that
> made that happen.
>
> Regardless, add OPTIMIZER_HIDE_VAR() to "hide" the value of the mask for
> safety against any future compiler optimizations.
>
> Signed-off-by: Eric Biggers <ebiggers@kernel.org>
> ---
> lib/crypto/poly1305-donna32.c | 1 +
> lib/crypto/poly1305-donna64.c | 1 +
> 2 files changed, 2 insertions(+)
>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
> diff --git a/lib/crypto/poly1305-donna32.c
> b/lib/crypto/poly1305-donna32.c
> index 5977785cd76e..73fe9181296c 100644
> --- a/lib/crypto/poly1305-donna32.c
> +++ b/lib/crypto/poly1305-donna32.c
> @@ -167,6 +167,7 @@ void poly1305_core_emit(const struct poly1305_state
> *state, const u32 nonce[4],
>
> /* select h if h < p, or h + -p if h >= p */
> mask = (g4 >> ((sizeof(u32) * 8) - 1)) - 1;
> + OPTIMIZER_HIDE_VAR(mask);
> g0 &= mask;
> g1 &= mask;
> g2 &= mask;
> diff --git a/lib/crypto/poly1305-donna64.c
> b/lib/crypto/poly1305-donna64.c
> index d0e4234c1c4c..402a3459ca49 100644
> --- a/lib/crypto/poly1305-donna64.c
> +++ b/lib/crypto/poly1305-donna64.c
> @@ -152,6 +152,7 @@ void poly1305_core_emit(const struct poly1305_state
> *state, const u32 nonce[4],
>
> /* select h if h < p, or h + -p if h >= p */
> c = (g2 >> ((sizeof(u64) * 8) - 1)) - 1;
> + OPTIMIZER_HIDE_VAR(c);
> g0 &= c;
> g1 &= c;
> g2 &= c;
>
> base-commit: 2a500a04d6f969318c05f46aedb6e73fc1963a00
> --
> 2.56.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] lib/crypto: poly1305: Hide the mask value from compilers
2026-10-31 4:26 [PATCH] lib/crypto: poly1305: Hide the mask value from compilers Eric Biggers
2026-11-02 9:16 ` Ard Biesheuvel
@ 2026-11-03 23:26 ` Eric Biggers
1 sibling, 0 replies; 3+ messages in thread
From: Eric Biggers @ 2026-11-03 23:26 UTC (permalink / raw)
To: linux-crypto; +Cc: Ard Biesheuvel, Jason A . Donenfeld, Herbert Xu
On Fri, Oct 30, 2026 at 09:26:37PM -0700, Eric Biggers wrote:
> poly1305_core_emit() does a constant-time select between h and h - p,
> where h is the accumulator and p is the Poly1305 prime of 2^130 - 5.
>
> The mask used in this select isn't hidden from the compiler, though, so
> the compiler can infer that it's either all 0's or all 1's.
>
> In theory, the compiler could then use that to recognize the select, and
> "optimize" it with a branch.
>
> Fortunately, in practice, I couldn't find any gcc or clang options that
> made that happen.
>
> Regardless, add OPTIMIZER_HIDE_VAR() to "hide" the value of the mask for
> safety against any future compiler optimizations.
>
> Signed-off-by: Eric Biggers <ebiggers@kernel.org>
> ---
> lib/crypto/poly1305-donna32.c | 1 +
> lib/crypto/poly1305-donna64.c | 1 +
> 2 files changed, 2 insertions(+)
Applied to https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git/log/?h=libcrypto-next
- Eric
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-11-03 23:26 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-31 4:26 [PATCH] lib/crypto: poly1305: Hide the mask value from compilers Eric Biggers
2026-11-02 9:16 ` Ard Biesheuvel
2026-11-03 23:26 ` Eric Biggers
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.