From 8f77fab82486c19ab48eee07718e190f76e6ea9a Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Wed, 18 Jan 2017 12:12:34 -0500 Subject: [PATCH] Replace div-spoiler hack with simpler code This comes from a comment in GH issue #1027. Andy wrote the code, Rich made the PR. Reviewed-by: Andy Polyakov Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/2253) --- ssl/record/ssl3_record.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c index 0190ecfa25..fc4723685c 100644 --- a/ssl/record/ssl3_record.c +++ b/ssl/record/ssl3_record.c @@ -1309,13 +1309,13 @@ void ssl3_cbc_copy_mac(unsigned char *out, */ size_t mac_end = rec->length; size_t mac_start = mac_end - md_size; + size_t in_mac; /* * scan_start contains the number of bytes that we can ignore because the * MAC's position can only vary by 255 bytes. */ size_t scan_start = 0; size_t i, j; - size_t div_spoiler; size_t rotate_offset; OPENSSL_assert(rec->orig_len >= md_size); @@ -1328,24 +1328,19 @@ void ssl3_cbc_copy_mac(unsigned char *out, /* This information is public so it's safe to branch based on it. */ if (rec->orig_len > md_size + 255 + 1) scan_start = rec->orig_len - (md_size + 255 + 1); - /* - * div_spoiler contains a multiple of md_size that is used to cause the - * modulo operation to be constant time. Without this, the time varies - * based on the amount of padding when running on Intel chips at least. - * The aim of right-shifting md_size is so that the compiler doesn't - * figure out that it can remove div_spoiler as that would require it to - * prove that md_size is always even, which I hope is beyond it. - */ - div_spoiler = md_size >> 1; - div_spoiler <<= (sizeof(div_spoiler) - 1) * 8; - rotate_offset = (div_spoiler + mac_start - scan_start) % md_size; + in_mac = 0; + rotate_offset = 0; memset(rotated_mac, 0, md_size); for (i = scan_start, j = 0; i < rec->orig_len; i++) { - unsigned char mac_started = constant_time_ge_8_s(i, mac_start); - unsigned char mac_ended = constant_time_ge_8_s(i, mac_end); + size_t mac_started = constant_time_eq_s(i, mac_start); + size_t mac_ended = constant_time_lt_s(i, mac_end); unsigned char b = rec->data[i]; - rotated_mac[j++] |= b & mac_started & ~mac_ended; + + in_mac |= mac_started; + in_mac &= mac_ended; + rotate_offset |= j & mac_started; + rotated_mac[j++] |= b & in_mac; j &= constant_time_lt_s(j, md_size); } -- 2.25.1