Skip to contentSkip to conversation

lib/crypto: poly1305: Hide the mask value from compilers

PATCH Applied Eric Biggers 2 participants 3 messages Oct 31 – Nov 3

Subsystems (2)
lore
Share & tools
lore

Eric Biggers

author maintainer
#0 lore raw

PATCH 1/1 lib/crypto: poly1305: Hide the mask value from compilers

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.

---
 lib/crypto/poly1305-donna32.c | 1 +
 lib/crypto/poly1305-donna64.c | 1 +
 2 files changed, 2 insertions(+)
lib/crypto/poly1305-donna32.c +1 -0
index 5977785cd76e..73fe9181296c 100644
@@ -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;
lib/crypto/poly1305-donna64.c +1 -0
index d0e4234c1c4c..402a3459ca49 100644
@@ -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

Signature · 1 line
2.56.0
maintainer Reviewed-by on v1 1/1
#1 lore raw
Quoted 12 lines · 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.

Quoted 9 lines

Regardless, add OPTIMIZER_HIDE_VAR() to "hide" the value of the mask for safety against any future compiler optimizations.

---
 lib/crypto/poly1305-donna32.c | 1 +
 lib/crypto/poly1305-donna64.c | 1 +
 2 files changed, 2 insertions(+)
Quoted 32 lines
lib/crypto/poly1305-donna32.c +1 -0
index 5977785cd76e..73fe9181296c 100644
@@ -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;
lib/crypto/poly1305-donna32.c +0 -0
 	g2 &= mask;
lib/crypto/poly1305-donna64.c +1 -0
index d0e4234c1c4c..402a3459ca49 100644
@@ -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

Signature · 1 line
2.56.0
author maintainer Applied
#2 lore raw
In reply to Eric Biggers
Quoted 12 lines · 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.

Quoted 8 lines

Regardless, add OPTIMIZER_HIDE_VAR() to "hide" the value of the mask for safety against any future compiler optimizations.

---
 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