Loading include/internal/constant_time_locl.h +49 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ #ifndef HEADER_CONSTANT_TIME_LOCL_H # define HEADER_CONSTANT_TIME_LOCL_H # include <stdlib.h> # include <openssl/e_os2.h> /* For 'ossl_inline' */ #ifdef __cplusplus Loading Loading @@ -102,12 +103,22 @@ static ossl_inline unsigned int constant_time_msb(unsigned int a) return 0 - (a >> (sizeof(a) * 8 - 1)); } static ossl_inline size_t constant_time_msb_s(size_t a) { return 0 - (a >> (sizeof(a) * 8 - 1)); } static ossl_inline unsigned int constant_time_lt(unsigned int a, unsigned int b) { return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b))); } static ossl_inline size_t constant_time_lt_s(size_t a, size_t b) { return constant_time_msb_s(a ^ ((a ^ b) | ((a - b) ^ b))); } static ossl_inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b) { Loading @@ -120,17 +131,32 @@ static ossl_inline unsigned int constant_time_ge(unsigned int a, return ~constant_time_lt(a, b); } static ossl_inline size_t constant_time_ge_s(size_t a, size_t b) { return ~constant_time_lt_s(a, b); } static ossl_inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b) { return (unsigned char)(constant_time_ge(a, b)); } static ossl_inline unsigned char constant_time_ge_8_s(size_t a, size_t b) { return (unsigned char)(constant_time_ge_s(a, b)); } static ossl_inline unsigned int constant_time_is_zero(unsigned int a) { return constant_time_msb(~a & (a - 1)); } static ossl_inline size_t constant_time_is_zero_s(size_t a) { return constant_time_msb_s(~a & (a - 1)); } static ossl_inline unsigned char constant_time_is_zero_8(unsigned int a) { return (unsigned char)(constant_time_is_zero(a)); Loading @@ -142,12 +168,22 @@ static ossl_inline unsigned int constant_time_eq(unsigned int a, return constant_time_is_zero(a ^ b); } static ossl_inline size_t constant_time_eq_s(size_t a, size_t b) { return constant_time_is_zero_s(a ^ b); } static ossl_inline unsigned char constant_time_eq_8(unsigned int a, unsigned int b) { return (unsigned char)(constant_time_eq(a, b)); } static ossl_inline unsigned char constant_time_eq_8_s(size_t a, size_t b) { return (unsigned char)(constant_time_eq_s(a, b)); } static ossl_inline unsigned int constant_time_eq_int(int a, int b) { return constant_time_eq((unsigned)(a), (unsigned)(b)); Loading @@ -165,6 +201,13 @@ static ossl_inline unsigned int constant_time_select(unsigned int mask, return (mask & a) | (~mask & b); } static ossl_inline size_t constant_time_select_s(size_t mask, size_t a, size_t b) { return (mask & a) | (~mask & b); } static ossl_inline unsigned char constant_time_select_8(unsigned char mask, unsigned char a, unsigned char b) Loading @@ -178,6 +221,12 @@ static ossl_inline int constant_time_select_int(unsigned int mask, int a, return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b))); } static ossl_inline int constant_time_select_int_s(size_t mask, int a, int b) { return (int)(constant_time_select((unsigned)mask, (unsigned)(a), (unsigned)(b))); } #ifdef __cplusplus } #endif Loading ssl/record/ssl3_record.c +19 −19 Original line number Diff line number Diff line Loading @@ -1112,7 +1112,7 @@ int ssl3_cbc_remove_padding(SSL3_RECORD *rec, size_t block_size, size_t mac_size) { size_t padding_length; unsigned good; size_t good; const size_t overhead = 1 /* padding length byte */ + mac_size; /* Loading @@ -1122,11 +1122,11 @@ int ssl3_cbc_remove_padding(SSL3_RECORD *rec, return 0; padding_length = rec->data[rec->length - 1]; good = constant_time_ge(rec->length, padding_length + overhead); good = constant_time_ge_s(rec->length, padding_length + overhead); /* SSLv3 requires that the padding is minimal. */ good &= constant_time_ge(block_size, padding_length + 1); good &= constant_time_ge_s(block_size, padding_length + 1); rec->length -= good & (padding_length + 1); return constant_time_select_int(good, 1, -1); return constant_time_select_int_s(good, 1, -1); } /*- Loading @@ -1146,7 +1146,7 @@ int tls1_cbc_remove_padding(const SSL *s, SSL3_RECORD *rec, size_t block_size, size_t mac_size) { unsigned good; size_t good; size_t padding_length, to_check, i; const size_t overhead = 1 /* padding length byte */ + mac_size; /* Check if version requires explicit IV */ Loading Loading @@ -1174,7 +1174,7 @@ int tls1_cbc_remove_padding(const SSL *s, return 1; } good = constant_time_ge(rec->length, overhead + padding_length); good = constant_time_ge_s(rec->length, overhead + padding_length); /* * The padding consists of a length byte at the end of the record and * then that many bytes of padding, all with the same value as the length Loading @@ -1189,7 +1189,7 @@ int tls1_cbc_remove_padding(const SSL *s, to_check = rec->length; for (i = 0; i < to_check; i++) { unsigned char mask = constant_time_ge_8(padding_length, i); unsigned char mask = constant_time_ge_8_s(padding_length, i); unsigned char b = rec->data[rec->length - 1 - i]; /* * The final |padding_length+1| bytes should all have the value Loading @@ -1202,10 +1202,10 @@ int tls1_cbc_remove_padding(const SSL *s, * If any of the final |padding_length+1| bytes had the wrong value, one * or more of the lower eight bits of |good| will be cleared. */ good = constant_time_eq(0xff, good & 0xff); good = constant_time_eq_s(0xff, good & 0xff); rec->length -= good & (padding_length + 1); return constant_time_select_int(good, 1, -1); return constant_time_select_int_s(good, 1, -1); } /*- Loading Loading @@ -1248,9 +1248,9 @@ void ssl3_cbc_copy_mac(unsigned char *out, * MAC's position can only vary by 255 bytes. */ size_t scan_start = 0; unsigned i, j; unsigned div_spoiler; unsigned rotate_offset; size_t i, j; size_t div_spoiler; size_t rotate_offset; OPENSSL_assert(rec->orig_len >= md_size); OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); Loading @@ -1276,11 +1276,11 @@ void ssl3_cbc_copy_mac(unsigned char *out, 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(i, mac_start); unsigned char mac_ended = constant_time_ge_8(i, mac_end); unsigned char mac_started = constant_time_ge_8_s(i, mac_start); unsigned char mac_ended = constant_time_ge_8_s(i, mac_end); unsigned char b = rec->data[i]; rotated_mac[j++] |= b & mac_started & ~mac_ended; j &= constant_time_lt(j, md_size); j &= constant_time_lt_s(j, md_size); } /* Now rotate the MAC */ Loading @@ -1290,17 +1290,17 @@ void ssl3_cbc_copy_mac(unsigned char *out, /* in case cache-line is 32 bytes, touch second line */ ((volatile unsigned char *)rotated_mac)[rotate_offset ^ 32]; out[j++] = rotated_mac[rotate_offset++]; rotate_offset &= constant_time_lt(rotate_offset, md_size); rotate_offset &= constant_time_lt_s(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); rotate_offset &= constant_time_lt_s(rotate_offset, md_size); for (i = 0; i < md_size; i++) { for (j = 0; j < md_size; j++) out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset); out[j] |= rotated_mac[i] & constant_time_eq_8_s(j, rotate_offset); rotate_offset++; rotate_offset &= constant_time_lt(rotate_offset, md_size); rotate_offset &= constant_time_lt_s(rotate_offset, md_size); } #endif } Loading ssl/s3_cbc.c +4 −4 Original line number Diff line number Diff line Loading @@ -400,8 +400,8 @@ int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, for (i = num_starting_blocks; i <= num_starting_blocks + variance_blocks; i++) { unsigned char block[MAX_HASH_BLOCK_SIZE]; unsigned char is_block_a = constant_time_eq_8(i, index_a); unsigned char is_block_b = constant_time_eq_8(i, index_b); unsigned char is_block_a = constant_time_eq_8_s(i, index_a); unsigned char is_block_b = constant_time_eq_8_s(i, index_b); for (j = 0; j < md_block_size; j++) { unsigned char b = 0, is_past_c, is_past_cp1; if (k < header_length) Loading @@ -410,8 +410,8 @@ int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, b = data[k - header_length]; k++; is_past_c = is_block_a & constant_time_ge_8(j, c); is_past_cp1 = is_block_a & constant_time_ge_8(j, c + 1); is_past_c = is_block_a & constant_time_ge_8_s(j, c); is_past_cp1 = is_block_a & constant_time_ge_8_s(j, c + 1); /* * If this is the block containing the end of the application * data, and we are at the offset for the 0x80 value, then Loading Loading
include/internal/constant_time_locl.h +49 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ #ifndef HEADER_CONSTANT_TIME_LOCL_H # define HEADER_CONSTANT_TIME_LOCL_H # include <stdlib.h> # include <openssl/e_os2.h> /* For 'ossl_inline' */ #ifdef __cplusplus Loading Loading @@ -102,12 +103,22 @@ static ossl_inline unsigned int constant_time_msb(unsigned int a) return 0 - (a >> (sizeof(a) * 8 - 1)); } static ossl_inline size_t constant_time_msb_s(size_t a) { return 0 - (a >> (sizeof(a) * 8 - 1)); } static ossl_inline unsigned int constant_time_lt(unsigned int a, unsigned int b) { return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b))); } static ossl_inline size_t constant_time_lt_s(size_t a, size_t b) { return constant_time_msb_s(a ^ ((a ^ b) | ((a - b) ^ b))); } static ossl_inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b) { Loading @@ -120,17 +131,32 @@ static ossl_inline unsigned int constant_time_ge(unsigned int a, return ~constant_time_lt(a, b); } static ossl_inline size_t constant_time_ge_s(size_t a, size_t b) { return ~constant_time_lt_s(a, b); } static ossl_inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b) { return (unsigned char)(constant_time_ge(a, b)); } static ossl_inline unsigned char constant_time_ge_8_s(size_t a, size_t b) { return (unsigned char)(constant_time_ge_s(a, b)); } static ossl_inline unsigned int constant_time_is_zero(unsigned int a) { return constant_time_msb(~a & (a - 1)); } static ossl_inline size_t constant_time_is_zero_s(size_t a) { return constant_time_msb_s(~a & (a - 1)); } static ossl_inline unsigned char constant_time_is_zero_8(unsigned int a) { return (unsigned char)(constant_time_is_zero(a)); Loading @@ -142,12 +168,22 @@ static ossl_inline unsigned int constant_time_eq(unsigned int a, return constant_time_is_zero(a ^ b); } static ossl_inline size_t constant_time_eq_s(size_t a, size_t b) { return constant_time_is_zero_s(a ^ b); } static ossl_inline unsigned char constant_time_eq_8(unsigned int a, unsigned int b) { return (unsigned char)(constant_time_eq(a, b)); } static ossl_inline unsigned char constant_time_eq_8_s(size_t a, size_t b) { return (unsigned char)(constant_time_eq_s(a, b)); } static ossl_inline unsigned int constant_time_eq_int(int a, int b) { return constant_time_eq((unsigned)(a), (unsigned)(b)); Loading @@ -165,6 +201,13 @@ static ossl_inline unsigned int constant_time_select(unsigned int mask, return (mask & a) | (~mask & b); } static ossl_inline size_t constant_time_select_s(size_t mask, size_t a, size_t b) { return (mask & a) | (~mask & b); } static ossl_inline unsigned char constant_time_select_8(unsigned char mask, unsigned char a, unsigned char b) Loading @@ -178,6 +221,12 @@ static ossl_inline int constant_time_select_int(unsigned int mask, int a, return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b))); } static ossl_inline int constant_time_select_int_s(size_t mask, int a, int b) { return (int)(constant_time_select((unsigned)mask, (unsigned)(a), (unsigned)(b))); } #ifdef __cplusplus } #endif Loading
ssl/record/ssl3_record.c +19 −19 Original line number Diff line number Diff line Loading @@ -1112,7 +1112,7 @@ int ssl3_cbc_remove_padding(SSL3_RECORD *rec, size_t block_size, size_t mac_size) { size_t padding_length; unsigned good; size_t good; const size_t overhead = 1 /* padding length byte */ + mac_size; /* Loading @@ -1122,11 +1122,11 @@ int ssl3_cbc_remove_padding(SSL3_RECORD *rec, return 0; padding_length = rec->data[rec->length - 1]; good = constant_time_ge(rec->length, padding_length + overhead); good = constant_time_ge_s(rec->length, padding_length + overhead); /* SSLv3 requires that the padding is minimal. */ good &= constant_time_ge(block_size, padding_length + 1); good &= constant_time_ge_s(block_size, padding_length + 1); rec->length -= good & (padding_length + 1); return constant_time_select_int(good, 1, -1); return constant_time_select_int_s(good, 1, -1); } /*- Loading @@ -1146,7 +1146,7 @@ int tls1_cbc_remove_padding(const SSL *s, SSL3_RECORD *rec, size_t block_size, size_t mac_size) { unsigned good; size_t good; size_t padding_length, to_check, i; const size_t overhead = 1 /* padding length byte */ + mac_size; /* Check if version requires explicit IV */ Loading Loading @@ -1174,7 +1174,7 @@ int tls1_cbc_remove_padding(const SSL *s, return 1; } good = constant_time_ge(rec->length, overhead + padding_length); good = constant_time_ge_s(rec->length, overhead + padding_length); /* * The padding consists of a length byte at the end of the record and * then that many bytes of padding, all with the same value as the length Loading @@ -1189,7 +1189,7 @@ int tls1_cbc_remove_padding(const SSL *s, to_check = rec->length; for (i = 0; i < to_check; i++) { unsigned char mask = constant_time_ge_8(padding_length, i); unsigned char mask = constant_time_ge_8_s(padding_length, i); unsigned char b = rec->data[rec->length - 1 - i]; /* * The final |padding_length+1| bytes should all have the value Loading @@ -1202,10 +1202,10 @@ int tls1_cbc_remove_padding(const SSL *s, * If any of the final |padding_length+1| bytes had the wrong value, one * or more of the lower eight bits of |good| will be cleared. */ good = constant_time_eq(0xff, good & 0xff); good = constant_time_eq_s(0xff, good & 0xff); rec->length -= good & (padding_length + 1); return constant_time_select_int(good, 1, -1); return constant_time_select_int_s(good, 1, -1); } /*- Loading Loading @@ -1248,9 +1248,9 @@ void ssl3_cbc_copy_mac(unsigned char *out, * MAC's position can only vary by 255 bytes. */ size_t scan_start = 0; unsigned i, j; unsigned div_spoiler; unsigned rotate_offset; size_t i, j; size_t div_spoiler; size_t rotate_offset; OPENSSL_assert(rec->orig_len >= md_size); OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); Loading @@ -1276,11 +1276,11 @@ void ssl3_cbc_copy_mac(unsigned char *out, 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(i, mac_start); unsigned char mac_ended = constant_time_ge_8(i, mac_end); unsigned char mac_started = constant_time_ge_8_s(i, mac_start); unsigned char mac_ended = constant_time_ge_8_s(i, mac_end); unsigned char b = rec->data[i]; rotated_mac[j++] |= b & mac_started & ~mac_ended; j &= constant_time_lt(j, md_size); j &= constant_time_lt_s(j, md_size); } /* Now rotate the MAC */ Loading @@ -1290,17 +1290,17 @@ void ssl3_cbc_copy_mac(unsigned char *out, /* in case cache-line is 32 bytes, touch second line */ ((volatile unsigned char *)rotated_mac)[rotate_offset ^ 32]; out[j++] = rotated_mac[rotate_offset++]; rotate_offset &= constant_time_lt(rotate_offset, md_size); rotate_offset &= constant_time_lt_s(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); rotate_offset &= constant_time_lt_s(rotate_offset, md_size); for (i = 0; i < md_size; i++) { for (j = 0; j < md_size; j++) out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset); out[j] |= rotated_mac[i] & constant_time_eq_8_s(j, rotate_offset); rotate_offset++; rotate_offset &= constant_time_lt(rotate_offset, md_size); rotate_offset &= constant_time_lt_s(rotate_offset, md_size); } #endif } Loading
ssl/s3_cbc.c +4 −4 Original line number Diff line number Diff line Loading @@ -400,8 +400,8 @@ int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, for (i = num_starting_blocks; i <= num_starting_blocks + variance_blocks; i++) { unsigned char block[MAX_HASH_BLOCK_SIZE]; unsigned char is_block_a = constant_time_eq_8(i, index_a); unsigned char is_block_b = constant_time_eq_8(i, index_b); unsigned char is_block_a = constant_time_eq_8_s(i, index_a); unsigned char is_block_b = constant_time_eq_8_s(i, index_b); for (j = 0; j < md_block_size; j++) { unsigned char b = 0, is_past_c, is_past_cp1; if (k < header_length) Loading @@ -410,8 +410,8 @@ int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, b = data[k - header_length]; k++; is_past_c = is_block_a & constant_time_ge_8(j, c); is_past_cp1 = is_block_a & constant_time_ge_8(j, c + 1); is_past_c = is_block_a & constant_time_ge_8_s(j, c); is_past_cp1 = is_block_a & constant_time_ge_8_s(j, c + 1); /* * If this is the block containing the end of the application * data, and we are at the offset for the 0x80 value, then Loading