I've been watching a thread on the OpenSSL mailing list. The thread is titled CBC ciphers + TLS 1.0 protocol does not work in OpenSSL 1.0.2d.
OpenSSL 1.0.2d had intermittent problems due to the following. It showed up under Microsoft's WinCE compiler. The idea is to propagate the high bit to all other bits:
#define DUPLICATE_MSB_TO_ALL(x) ( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) )
#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x)))
static unsigned char constant_time_eq_8(unsigned a, unsigned b)
{
unsigned c = a ^ b;
c--;
return DUPLICATE_MSB_TO_ALL_8(c);
}
OpenSSL attempts to follow C89. I believe this is implementation defined behavior due to shifting of a negative value on a 2's compliment machine.
However, what the OP found was it was affected by optimizations. Without optimizations the code produced correct results. With optimizations the code produced incorrect results.
My question is, when relying on implementation defined behavior, is it legal or expected to see results change depending on optimizations?