diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 65fc56ef..58a32bb7 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -3918,9 +3918,6 @@ typedef struct ssl3_state_st { uint8_t server_random[SSL3_RANDOM_SIZE]; uint8_t client_random[SSL3_RANDOM_SIZE]; - /* flags for countermeasure against known-IV weakness */ - int need_record_splitting; - /* have_version is true if the connection's final version is known. Otherwise * the version has not been negotiated yet. */ char have_version; diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 51b7082b..81190258 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -369,19 +369,7 @@ int tls1_change_cipher_state(SSL *s, int which) { evp_aead_seal, ssl3_version_from_wire(s, s->version), s->s3->tmp.new_cipher, key, key_len, mac_secret, mac_secret_len, iv, iv_len); - if (s->aead_write_ctx == NULL) { - return 0; - } - - s->s3->need_record_splitting = 0; - if (!SSL_USE_EXPLICIT_IV(s) && - (s->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0 && - SSL_CIPHER_is_block_cipher(s->s3->tmp.new_cipher)) { - /* Enable 1/n-1 record-splitting to randomize the IV. See - * https://www.openssl.org/~bodo/tls-cbc.txt and the BEAST attack. */ - s->s3->need_record_splitting = 1; - } - return 1; + return s->aead_write_ctx != NULL; } int tls1_setup_key_block(SSL *s) { diff --git a/ssl/tls_record.c b/ssl/tls_record.c index e3eccd7e..3381eae3 100644 --- a/ssl/tls_record.c +++ b/ssl/tls_record.c @@ -122,6 +122,14 @@ * forever. */ static const uint8_t kMaxEmptyRecords = 32; +/* ssl_needs_record_splitting returns one if |ssl|'s current outgoing cipher + * state needs record-splitting and zero otherwise. */ +static int ssl_needs_record_splitting(const SSL *ssl) { + return !SSL_USE_EXPLICIT_IV(ssl) && ssl->aead_write_ctx != NULL && + (ssl->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0 && + SSL_CIPHER_is_block_cipher(ssl->aead_write_ctx->cipher); +} + size_t ssl_record_prefix_len(const SSL *ssl) { if (SSL_IS_DTLS(ssl)) { return DTLS1_RT_HEADER_LENGTH + @@ -139,7 +147,7 @@ size_t ssl_seal_prefix_len(const SSL *ssl) { } else { size_t ret = SSL3_RT_HEADER_LENGTH + SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_write_ctx); - if (ssl->s3->need_record_splitting) { + if (ssl_needs_record_splitting(ssl)) { ret += SSL3_RT_HEADER_LENGTH; ret += ssl_cipher_get_record_split_len(ssl->aead_write_ctx->cipher); } @@ -154,7 +162,7 @@ size_t ssl_max_seal_overhead(const SSL *ssl) { } else { size_t ret = SSL3_RT_HEADER_LENGTH + SSL_AEAD_CTX_max_overhead(ssl->aead_write_ctx); - if (ssl->s3->need_record_splitting) { + if (ssl_needs_record_splitting(ssl)) { ret *= 2; } return ret; @@ -300,8 +308,8 @@ static int do_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, int tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, uint8_t type, const uint8_t *in, size_t in_len) { size_t frag_len = 0; - if (ssl->s3->need_record_splitting && type == SSL3_RT_APPLICATION_DATA && - in_len > 1) { + if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 && + ssl_needs_record_splitting(ssl)) { /* |do_seal_record| will notice if it clobbers |in[0]|, but not if it * aliases the rest of |in|. */ if (in + 1 <= out && out < in + in_len) {