lib/crypto: poly1305: Hide the mask value from compilers
Subsystems (2)
Eric Biggers
maintainerPATCH 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
@@ -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
@@ -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
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.Signed-off-by Eric Biggers <[email protected]>--- 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@@ -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
-0g2 &= mask;lib/crypto/poly1305-donna64.c +1
-0@@ -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:
2a500a04d6f969318c05f46aedb6e73fc1963a00Signature · 1 line
2.56.0
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.Signed-off-by Eric Biggers <[email protected]>--- 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