diff --git a/crypto/fipsmodule/ec/asm/p256-x86_64-asm.pl b/crypto/fipsmodule/ec/asm/p256-x86_64-asm.pl index 81fc85dd2..e40aaa92d 100755 --- a/crypto/fipsmodule/ec/asm/p256-x86_64-asm.pl +++ b/crypto/fipsmodule/ec/asm/p256-x86_64-asm.pl @@ -3158,17 +3158,24 @@ $code.=<<___; or $acc5, $acc4 # see if result is zero or $acc0, $acc4 - or $acc1, $acc4 + or $acc1, $acc4 # !is_equal(U1, U2) - .byte 0x3e # predict taken - jnz .Ladd_proceed$x # is_equal(U1,U2)? movq %xmm2, $acc0 movq %xmm3, $acc1 - test $acc0, $acc0 - jnz .Ladd_proceed$x # (in1infty || in2infty)? - test $acc1, $acc1 - jz .Ladd_double$x # is_equal(S1,S2)? + or $acc0, $acc4 + .byte 0x3e # predict taken + jnz .Ladd_proceed$x # !is_equal(U1, U2) || in1infty || in2infty + # We now know A = B or A = -B and neither is infinity. Compare the + # y-coordinates via S1 and S2. + test $acc1, $acc1 + jz .Ladd_double$x # is_equal(S1, S2) + + # A = -B, so the result is infinity. + # + # TODO(davidben): Does .Ladd_proceed handle this case? It seems to, in + # which case we should eliminate this special-case and simplify the + # timing analysis. movq %xmm0, $r_ptr # restore $r_ptr pxor %xmm0, %xmm0 movdqu %xmm0, 0x00($r_ptr) diff --git a/crypto/fipsmodule/ec/ecp_nistz256.c b/crypto/fipsmodule/ec/ecp_nistz256.c index aecf4ef3a..a0de1d161 100644 --- a/crypto/fipsmodule/ec/ecp_nistz256.c +++ b/crypto/fipsmodule/ec/ecp_nistz256.c @@ -154,9 +154,8 @@ void GFp_nistz256_point_add(P256_POINT *r, const P256_POINT *a, const P256_POINT elem_mul_mont(U2, in2_x, Z1sqr); /* U2 = X2*Z1^2 */ elem_sub(H, U2, U1); /* H = U2 - U1 */ - /* This should not happen during sign/ecdh, - * so no constant time violation */ - if (is_equal(U1, U2) && !in1infty && !in2infty) { + BN_ULONG is_exceptional = is_equal(U1, U2) & ~in1infty & ~in2infty; + if (is_exceptional) { if (is_equal(S1, S2)) { GFp_nistz256_point_double(r, a); } else { diff --git a/crypto/fipsmodule/ec/ecp_nistz384.inl b/crypto/fipsmodule/ec/ecp_nistz384.inl index 84eac751a..906f492f3 100644 --- a/crypto/fipsmodule/ec/ecp_nistz384.inl +++ b/crypto/fipsmodule/ec/ecp_nistz384.inl @@ -114,9 +114,8 @@ void GFp_nistz384_point_add(P384_POINT *r, const P384_POINT *a, elem_mul_mont(U2, in2_x, Z1sqr); /* U2 = X2*Z1^2 */ elem_sub(H, U2, U1); /* H = U2 - U1 */ - /* This should not happen during sign/ecdh, - * so no constant time violation */ - if (is_equal(U1, U2) && !in1infty && !in2infty) { + BN_ULONG is_exceptional = is_equal(U1, U2) & ~in1infty & ~in2infty; + if (is_exceptional) { if (is_equal(S1, S2)) { GFp_nistz384_point_double(r, a); } else {