diff --git a/crypto/cipher/e_tls.c b/crypto/cipher/e_tls.c index b98235af..74e9dcec 100644 --- a/crypto/cipher/e_tls.c +++ b/crypto/cipher/e_tls.c @@ -306,7 +306,7 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, int padding_ok; unsigned data_plus_mac_len, data_len; if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE) { - padding_ok = EVP_tls1_cbc_remove_padding( + padding_ok = EVP_tls_cbc_remove_padding( &data_plus_mac_len, out, total, EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx), (unsigned)HMAC_size(&tls_ctx->hmac_ctx)); @@ -342,18 +342,17 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t record_mac_tmp[EVP_MAX_MD_SIZE]; uint8_t *record_mac; if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE && - EVP_ssl3_cbc_record_digest_supported(tls_ctx->hmac_ctx.md)) { - if (!EVP_ssl3_cbc_digest_record(tls_ctx->hmac_ctx.md, mac, &mac_len, - ad_fixed, out, data_plus_mac_len, total, - tls_ctx->mac_key, tls_ctx->mac_key_len, - 0 /* !is_sslv3 */)) { + EVP_tls_cbc_record_digest_supported(tls_ctx->hmac_ctx.md)) { + if (!EVP_tls_cbc_digest_record(tls_ctx->hmac_ctx.md, mac, &mac_len, + ad_fixed, out, data_plus_mac_len, total, + tls_ctx->mac_key, tls_ctx->mac_key_len)) { OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BAD_DECRYPT); return 0; } assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx)); record_mac = record_mac_tmp; - EVP_ssl3_cbc_copy_mac(record_mac, mac_len, out, data_plus_mac_len, total); + EVP_tls_cbc_copy_mac(record_mac, mac_len, out, data_plus_mac_len, total); } else { /* We should support the constant-time path for all CBC-mode ciphers * implemented. */ @@ -379,7 +378,7 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, /* Perform the MAC check and the padding check in constant-time. It should be * safe to simply perform the padding check first, but it would not be under a * different choice of MAC location on padding failure. See - * EVP_tls1_cbc_remove_padding. */ + * EVP_tls_cbc_remove_padding. */ unsigned good = constant_time_eq_int(CRYPTO_memcmp(record_mac, mac, mac_len), 0); good &= constant_time_eq_int(padding_ok, 1); diff --git a/crypto/cipher/internal.h b/crypto/cipher/internal.h index e73d4a1d..bd49f57e 100644 --- a/crypto/cipher/internal.h +++ b/crypto/cipher/internal.h @@ -131,20 +131,7 @@ struct evp_aead_st { }; -/* EVP_ssl3_cbc_remove_padding determines the padding from the decrypted, SSLv3, - * CBC record in |in|. It sets |*out_len| to the length with the padding removed - * or |in_len| if invalid. - * - * block_size: the block size of the cipher used to encrypt the record. - * returns: - * 0: (in non-constant time) if the record is publicly invalid. - * 1: if the padding was valid - * -1: otherwise. */ -int EVP_ssl3_cbc_remove_padding(unsigned *out_len, - const uint8_t *in, unsigned in_len, - unsigned block_size, unsigned mac_size); - -/* EVP_tls1_cbc_get_padding determines the padding from the decrypted, TLS, CBC +/* EVP_tls_cbc_get_padding determines the padding from the decrypted, TLS, CBC * record in |in|. This decrypted record should not include any "decrypted" * explicit IV. It sets |*out_len| to the length with the padding removed or * |in_len| if invalid. @@ -154,11 +141,11 @@ int EVP_ssl3_cbc_remove_padding(unsigned *out_len, * 0: (in non-constant time) if the record is publicly invalid. * 1: if the padding was valid * -1: otherwise. */ -int EVP_tls1_cbc_remove_padding(unsigned *out_len, - const uint8_t *in, unsigned in_len, - unsigned block_size, unsigned mac_size); +int EVP_tls_cbc_remove_padding(unsigned *out_len, + const uint8_t *in, unsigned in_len, + unsigned block_size, unsigned mac_size); -/* EVP_ssl3_cbc_copy_mac copies |md_size| bytes from the end of the first +/* EVP_tls_cbc_copy_mac copies |md_size| bytes from the end of the first * |in_len| bytes of |in| to |out| in constant time (independent of the concrete * value of |in_len|, which may vary within a 256-byte window). |in| must point * to a buffer of |orig_len| bytes. @@ -166,19 +153,19 @@ int EVP_tls1_cbc_remove_padding(unsigned *out_len, * On entry: * orig_len >= in_len >= md_size * md_size <= EVP_MAX_MD_SIZE */ -void EVP_ssl3_cbc_copy_mac(uint8_t *out, unsigned md_size, - const uint8_t *in, unsigned in_len, - unsigned orig_len); +void EVP_tls_cbc_copy_mac(uint8_t *out, unsigned md_size, + const uint8_t *in, unsigned in_len, + unsigned orig_len); -/* EVP_ssl3_cbc_record_digest_supported returns 1 iff |md| is a hash function - * which EVP_ssl3_cbc_digest_record supports. */ -int EVP_ssl3_cbc_record_digest_supported(const EVP_MD *md); +/* EVP_tls_cbc_record_digest_supported returns 1 iff |md| is a hash function + * which EVP_tls_cbc_digest_record supports. */ +int EVP_tls_cbc_record_digest_supported(const EVP_MD *md); -/* EVP_ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS +/* EVP_tls_cbc_digest_record computes the MAC of a decrypted, padded TLS * record. * - * md: the hash function used in the SSLv3 MAC or HMAC. - * ssl3_cbc_record_digest_supported must return true for this hash. + * md: the hash function used in the HMAC. + * tls_cbc_record_digest_supported must return true for this hash. * md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written. * md_out_size: the number of output bytes is written here. * header: the 13-byte, TLS record header. @@ -187,18 +174,17 @@ int EVP_ssl3_cbc_record_digest_supported(const EVP_MD *md); * once the padding has been removed. * data_plus_mac_plus_padding_size: the public length of the whole * record, including padding. - * is_sslv3: non-zero if we are to use SSLv3. Otherwise, TLS. * * On entry: by virtue of having been through one of the remove_padding * functions, above, we know that data_plus_mac_size is large enough to contain * a padding byte and MAC. (If the padding was invalid, it might contain the * padding too. ) */ -int EVP_ssl3_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, - size_t *md_out_size, const uint8_t header[13], - const uint8_t *data, size_t data_plus_mac_size, - size_t data_plus_mac_plus_padding_size, - const uint8_t *mac_secret, - unsigned mac_secret_length, char is_sslv3); +int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, + size_t *md_out_size, const uint8_t header[13], + const uint8_t *data, size_t data_plus_mac_size, + size_t data_plus_mac_plus_padding_size, + const uint8_t *mac_secret, + unsigned mac_secret_length); #if defined(__cplusplus) } /* extern C */ diff --git a/crypto/cipher/tls_cbc.c b/crypto/cipher/tls_cbc.c index 0ace20c8..73952e5a 100644 --- a/crypto/cipher/tls_cbc.c +++ b/crypto/cipher/tls_cbc.c @@ -71,30 +71,9 @@ * supported by TLS.) */ #define MAX_HASH_BLOCK_SIZE 128 -int EVP_ssl3_cbc_remove_padding(unsigned *out_len, - const uint8_t *in, unsigned in_len, - unsigned block_size, unsigned mac_size) { - unsigned padding_length, good; - const unsigned overhead = 1 /* padding length byte */ + mac_size; - - /* These lengths are all public so we can test them in non-constant - * time. */ - if (overhead > in_len) { - return 0; - } - - padding_length = in[in_len - 1]; - good = constant_time_ge(in_len, padding_length + overhead); - /* SSLv3 requires that the padding is minimal. */ - good &= constant_time_ge(block_size, padding_length + 1); - padding_length = good & (padding_length + 1); - *out_len = in_len - padding_length; - return constant_time_select_int(good, 1, -1); -} - -int EVP_tls1_cbc_remove_padding(unsigned *out_len, - const uint8_t *in, unsigned in_len, - unsigned block_size, unsigned mac_size) { +int EVP_tls_cbc_remove_padding(unsigned *out_len, + const uint8_t *in, unsigned in_len, + unsigned block_size, unsigned mac_size) { unsigned padding_length, good, to_check, i; const unsigned overhead = 1 /* padding length byte */ + mac_size; @@ -142,16 +121,16 @@ int EVP_tls1_cbc_remove_padding(unsigned *out_len, return constant_time_select_int(good, 1, -1); } -/* If CBC_MAC_ROTATE_IN_PLACE is defined then EVP_ssl3_cbc_copy_mac is performed +/* If CBC_MAC_ROTATE_IN_PLACE is defined then EVP_tls_cbc_copy_mac is performed * with variable accesses in a 64-byte-aligned buffer. Assuming that this fits * into a single or pair of cache-lines, then the variable memory accesses don't * actually affect the timing. CPUs with smaller cache-lines [if any] are not * multi-core and are not considered vulnerable to cache-timing attacks. */ #define CBC_MAC_ROTATE_IN_PLACE -void EVP_ssl3_cbc_copy_mac(uint8_t *out, unsigned md_size, - const uint8_t *in, unsigned in_len, - unsigned orig_len) { +void EVP_tls_cbc_copy_mac(uint8_t *out, unsigned md_size, + const uint8_t *in, unsigned in_len, + unsigned orig_len) { #if defined(CBC_MAC_ROTATE_IN_PLACE) uint8_t rotated_mac_buf[64 + EVP_MAX_MD_SIZE]; uint8_t *rotated_mac; @@ -279,7 +258,7 @@ static void tls1_sha512_final_raw(void *ctx, uint8_t *md_out) { #undef LARGEST_DIGEST_CTX #define LARGEST_DIGEST_CTX SHA512_CTX -int EVP_ssl3_cbc_record_digest_supported(const EVP_MD *md) { +int EVP_tls_cbc_record_digest_supported(const EVP_MD *md) { switch (EVP_MD_type(md)) { case NID_sha1: case NID_sha256: @@ -291,12 +270,12 @@ int EVP_ssl3_cbc_record_digest_supported(const EVP_MD *md) { } } -int EVP_ssl3_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, - size_t *md_out_size, const uint8_t header[13], - const uint8_t *data, size_t data_plus_mac_size, - size_t data_plus_mac_plus_padding_size, - const uint8_t *mac_secret, - unsigned mac_secret_length, char is_sslv3) { +int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, + size_t *md_out_size, const uint8_t header[13], + const uint8_t *data, size_t data_plus_mac_size, + size_t data_plus_mac_plus_padding_size, + const uint8_t *mac_secret, + unsigned mac_secret_length) { union { double align; uint8_t c[sizeof(LARGEST_DIGEST_CTX)]; @@ -304,9 +283,8 @@ int EVP_ssl3_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, void (*md_final_raw)(void *ctx, uint8_t *md_out); void (*md_transform)(void *ctx, const uint8_t *block); unsigned md_size, md_block_size = 64; - unsigned sslv3_pad_length = 40, header_length, variance_blocks, len, - max_mac_bytes, num_blocks, num_starting_blocks, k, mac_end_offset, c, - index_a, index_b; + unsigned len, max_mac_bytes, num_blocks, num_starting_blocks, k, + mac_end_offset, c, index_a, index_b; unsigned int bits; /* at most 18 bits */ uint8_t length_bytes[MAX_HASH_BIT_COUNT_BYTES]; /* hmac_pad is the masked HMAC key. */ @@ -351,9 +329,8 @@ int EVP_ssl3_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, break; default: - /* ssl3_cbc_record_digest_supported should have been - * called first to check that the hash function is - * supported. */ + /* EVP_tls_cbc_record_digest_supported should have been called first to + * check that the hash function is supported. */ assert(0); *md_out_size = 0; return 0; @@ -363,34 +340,20 @@ int EVP_ssl3_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, assert(md_block_size <= MAX_HASH_BLOCK_SIZE); assert(md_size <= EVP_MAX_MD_SIZE); - header_length = 13; - if (is_sslv3) { - header_length = mac_secret_length + sslv3_pad_length + - 8 /* sequence number */ + 1 /* record type */ + - 2 /* record length */; - } + static const unsigned kHeaderLength = 13; - /* variance_blocks is the number of blocks of the hash that we have to + /* kVarianceBlocks is the number of blocks of the hash that we have to * calculate in constant time because they could be altered by the * padding value. * - * In SSLv3, the padding must be minimal so the end of the plaintext - * varies by, at most, 15+20 = 35 bytes. (We conservatively assume that - * the MAC size varies from 0..20 bytes.) In case the 9 bytes of hash - * termination (0x80 + 64-bit length) don't fit in the final block, we - * say that the final two blocks can vary based on the padding. - * * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not * required to be minimal. Therefore we say that the final six blocks - * can vary based on the padding. - * - * Later in the function, if the message is short and there obviously - * cannot be this many blocks then variance_blocks can be reduced. */ - variance_blocks = is_sslv3 ? 2 : 6; + * can vary based on the padding. */ + static const unsigned kVarianceBlocks = 6; + /* From now on we're dealing with the MAC, which conceptually has 13 - * bytes of `header' before the start of the data (TLS) or 71/75 bytes - * (SSLv3) */ - len = data_plus_mac_plus_padding_size + header_length; + * bytes of `header' before the start of the data. */ + len = data_plus_mac_plus_padding_size + kHeaderLength; /* max_mac_bytes contains the maximum bytes of bytes in the MAC, including * |header|, assuming that there's no padding. */ max_mac_bytes = len - md_size - 1; @@ -399,7 +362,7 @@ int EVP_ssl3_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, (max_mac_bytes + 1 + md_length_size + md_block_size - 1) / md_block_size; /* In order to calculate the MAC in constant time we have to handle * the final blocks specially because the padding value could cause the - * end to appear somewhere in the final |variance_blocks| blocks and we + * end to appear somewhere in the final |kVarianceBlocks| blocks and we * can't leak where. However, |num_starting_blocks| worth of data can * be hashed right away because no padding value can affect whether * they are plaintext. */ @@ -409,7 +372,7 @@ int EVP_ssl3_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, k = 0; /* mac_end_offset is the index just past the end of the data to be * MACed. */ - mac_end_offset = data_plus_mac_size + header_length - md_size; + mac_end_offset = data_plus_mac_size + kHeaderLength - md_size; /* c is the index of the 0x80 byte in the final hash block that * contains application data. */ c = mac_end_offset % md_block_size; @@ -420,32 +383,26 @@ int EVP_ssl3_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, * length, in bits. */ index_b = (mac_end_offset + md_length_size) / md_block_size; /* bits is the hash-length in bits. It includes the additional hash - * block for the masked HMAC key, or whole of |header| in the case of - * SSLv3. */ + * block for the masked HMAC key. */ - /* For SSLv3, if we're going to have any starting blocks then we need - * at least two because the header is larger than a single block. */ - if (num_blocks > variance_blocks + (is_sslv3 ? 1 : 0)) { - num_starting_blocks = num_blocks - variance_blocks; + if (num_blocks > kVarianceBlocks) { + num_starting_blocks = num_blocks - kVarianceBlocks; k = md_block_size * num_starting_blocks; } bits = 8 * mac_end_offset; - if (!is_sslv3) { - /* Compute the initial HMAC block. For SSLv3, the padding and - * secret bytes are included in |header| because they take more - * than a single block. */ - bits += 8 * md_block_size; - memset(hmac_pad, 0, md_block_size); - assert(mac_secret_length <= sizeof(hmac_pad)); - memcpy(hmac_pad, mac_secret, mac_secret_length); - for (i = 0; i < md_block_size; i++) { - hmac_pad[i] ^= 0x36; - } - md_transform(md_state.c, hmac_pad); + /* Compute the initial HMAC block. */ + bits += 8 * md_block_size; + memset(hmac_pad, 0, md_block_size); + assert(mac_secret_length <= sizeof(hmac_pad)); + memcpy(hmac_pad, mac_secret, mac_secret_length); + for (i = 0; i < md_block_size; i++) { + hmac_pad[i] ^= 0x36; } + md_transform(md_state.c, hmac_pad); + memset(length_bytes, 0, md_length_size - 4); length_bytes[md_length_size - 4] = (uint8_t)(bits >> 24); length_bytes[md_length_size - 3] = (uint8_t)(bits >> 16); @@ -453,26 +410,12 @@ int EVP_ssl3_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, length_bytes[md_length_size - 1] = (uint8_t)bits; if (k > 0) { - if (is_sslv3) { - /* The SSLv3 header is larger than a single block. - * overhang is the number of bytes beyond a single - * block that the header consumes: 7 bytes (SHA1). */ - unsigned overhang = header_length - md_block_size; - md_transform(md_state.c, header); - memcpy(first_block, header + md_block_size, overhang); - memcpy(first_block + overhang, data, md_block_size - overhang); - md_transform(md_state.c, first_block); - for (i = 1; i < k / md_block_size - 1; i++) { - md_transform(md_state.c, data + md_block_size * i - overhang); - } - } else { - /* k is a multiple of md_block_size. */ - memcpy(first_block, header, 13); - memcpy(first_block + 13, data, md_block_size - 13); - md_transform(md_state.c, first_block); - for (i = 1; i < k / md_block_size; i++) { - md_transform(md_state.c, data + md_block_size * i - 13); - } + /* k is a multiple of md_block_size. */ + memcpy(first_block, header, 13); + memcpy(first_block + 13, data, md_block_size - 13); + md_transform(md_state.c, first_block); + for (i = 1; i < k / md_block_size; i++) { + md_transform(md_state.c, data + md_block_size * i - 13); } } @@ -482,17 +425,17 @@ int EVP_ssl3_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, * it in constant time. If the |i==index_a| then we'll include the 0x80 * bytes and zero pad etc. For each block we selectively copy it, in * constant time, to |mac_out|. */ - for (i = num_starting_blocks; i <= num_starting_blocks + variance_blocks; + for (i = num_starting_blocks; i <= num_starting_blocks + kVarianceBlocks; i++) { uint8_t block[MAX_HASH_BLOCK_SIZE]; uint8_t is_block_a = constant_time_eq_8(i, index_a); uint8_t is_block_b = constant_time_eq_8(i, index_b); for (j = 0; j < md_block_size; j++) { uint8_t b = 0, is_past_c, is_past_cp1; - if (k < header_length) { + if (k < kHeaderLength) { b = header[k]; - } else if (k < data_plus_mac_plus_padding_size + header_length) { - b = data[k - header_length]; + } else if (k < data_plus_mac_plus_padding_size + kHeaderLength) { + b = data[k - kHeaderLength]; } k++; @@ -536,22 +479,13 @@ int EVP_ssl3_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, return 0; } - if (is_sslv3) { - /* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */ - memset(hmac_pad, 0x5c, sslv3_pad_length); - - EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length); - EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length); - EVP_DigestUpdate(&md_ctx, mac_out, md_size); - } else { - /* Complete the HMAC in the standard manner. */ - for (i = 0; i < md_block_size; i++) { - hmac_pad[i] ^= 0x6a; - } - - EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size); - EVP_DigestUpdate(&md_ctx, mac_out, md_size); + /* Complete the HMAC in the standard manner. */ + for (i = 0; i < md_block_size; i++) { + hmac_pad[i] ^= 0x6a; } + + EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size); + EVP_DigestUpdate(&md_ctx, mac_out, md_size); EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u); *md_out_size = md_out_size_u; EVP_MD_CTX_cleanup(&md_ctx);