summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2013-02-08 16:59:26 +0100
committerAndy Polyakov <appro@openssl.org>2013-02-08 17:00:46 +0100
commit47061af1062e36b87242810f7f5279ee7240b9e4 (patch)
treefae9f35fca34dfd5a59f109143c2c3a1f4d7f543
parent13e225300ff819754a2192229d8bbd329795d793 (diff)
downloadopenssl-new-47061af1062e36b87242810f7f5279ee7240b9e4.tar.gz
s3_cbc.c: get rid of expensive divisions [from master].
(cherry picked from commit e9baceab5a385e570706ca98dec768b2d89d1ac6)
-rw-r--r--ssl/s3_cbc.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/ssl/s3_cbc.c b/ssl/s3_cbc.c
index 0f605074a4..f8d8ee89c4 100644
--- a/ssl/s3_cbc.c
+++ b/ssl/s3_cbc.c
@@ -76,6 +76,13 @@
#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)))
+/* constant_time_lt returns 0xff if a<b and 0x00 otherwise. */
+static unsigned constant_time_lt(unsigned a, unsigned b)
+ {
+ a -= b;
+ return DUPLICATE_MSB_TO_ALL(a);
+ }
+
/* constant_time_ge returns 0xff if a>=b and 0x00 otherwise. */
static unsigned constant_time_ge(unsigned a, unsigned b)
{
@@ -84,7 +91,7 @@ static unsigned constant_time_ge(unsigned a, unsigned b)
}
/* constant_time_eq_8 returns 0xff if a==b and 0x00 otherwise. */
-static unsigned char constant_time_eq_8(unsigned char a, unsigned char b)
+static unsigned char constant_time_eq_8(unsigned a, unsigned b)
{
unsigned c = a ^ b;
c--;
@@ -288,16 +295,13 @@ void ssl3_cbc_copy_mac(unsigned char* out,
rotate_offset = (div_spoiler + mac_start - scan_start) % md_size;
memset(rotated_mac, 0, md_size);
- for (i = scan_start; i < orig_len;)
+ for (i = scan_start, j = 0; i < orig_len; i++)
{
- for (j = 0; j < md_size && i < orig_len; i++, j++)
- {
- unsigned char mac_started = constant_time_ge(i, mac_start);
- unsigned char mac_ended = constant_time_ge(i, mac_end);
- unsigned char b = 0;
- b = rec->data[i];
- rotated_mac[j] |= b & mac_started & ~mac_ended;
- }
+ unsigned char mac_started = constant_time_ge(i, mac_start);
+ unsigned char mac_ended = constant_time_ge(i, mac_end);
+ unsigned char b = rec->data[i];
+ rotated_mac[j++] |= b & mac_started & ~mac_ended;
+ j &= constant_time_lt(j,md_size);
}
/* Now rotate the MAC */
@@ -305,16 +309,19 @@ void ssl3_cbc_copy_mac(unsigned char* out,
j = 0;
for (i = 0; i < md_size; i++)
{
- unsigned char offset = (div_spoiler + rotate_offset + i) % md_size;
- out[j++] = rotated_mac[offset];
+ out[j++] = rotated_mac[rotate_offset++];
+ rotate_offset &= constant_time_lt(rotate_offset,md_size);
}
#else
memset(out, 0, md_size);
+ rotate_offset = md_size - rotate_offset;
+ rotate_offset &= constant_time_lt(rotate_offset,md_size);
for (i = 0; i < md_size; i++)
{
- unsigned char offset = (div_spoiler + md_size - rotate_offset + i) % md_size;
for (j = 0; j < md_size; j++)
- out[j] |= rotated_mac[i] & constant_time_eq_8(j, offset);
+ out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset);
+ rotate_offset++;
+ rotate_offset &= constant_time_lt(rotate_offset,md_size);
}
#endif
}