diff options
author | David Benjamin <davidben@chromium.org> | 2014-12-22 15:23:54 +0300 |
---|---|---|
committer | Adam Langley <agl@google.com> | 2015-01-14 23:33:41 +0300 |
commit | bbd8444d92dd7c4d19828177300579bcdc9f52f7 (patch) | |
tree | 7bd10e1ce4469ad22bbec7b3e56321727f168c24 /crypto | |
parent | ea72bd0b6033bc35d6a06da86e909a578d3d5daa (diff) |
Drop SSLv3 parts of crypto/cipher/tls_cbc.c.
CBC modes in SSLv3 are bust already with POODLE and we're moving away from it.
Align all the names from 'ssl3' and 'tls1' to 'tls', to match the names of the
TLS-only AEADs.
Change-Id: If742296a8e2633ef42a484e4d873b4a83558b6aa
Reviewed-on: https://boringssl-review.googlesource.com/2693
Reviewed-by: Adam Langley <agl@google.com>
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/cipher/e_tls.c | 15 | ||||
-rw-r--r-- | crypto/cipher/internal.h | 54 | ||||
-rw-r--r-- | crypto/cipher/tls_cbc.c | 176 |
3 files changed, 82 insertions, 163 deletions
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); |