Move aead_{read,write}_ctx and next_proto_negotiated into ssl->s3.

Both are connection state rather than configuration state. Notably this
cuts down more of SSL_clear that can't just use ssl_free + ssl_new.

Change-Id: I3c05b3ae86d4db8bd75f1cd21656f57fc5b55ca9
Reviewed-on: https://boringssl-review.googlesource.com/6835
Reviewed-by: Adam Langley <alangley@gmail.com>
diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c
index f2ade3a..7b7b2b0 100644
--- a/ssl/d1_pkt.c
+++ b/ssl/d1_pkt.c
@@ -300,7 +300,7 @@
     /* Make sure that we are not getting application data when we
      * are doing a handshake for the first time. */
     if (SSL_in_init(ssl) && (type == SSL3_RT_APPLICATION_DATA) &&
-        (ssl->aead_read_ctx == NULL)) {
+        (ssl->s3->aead_read_ctx == NULL)) {
       /* TODO(davidben): Is this check redundant with the handshake_func
        * check? */
       al = SSL_AD_UNEXPECTED_MESSAGE;
@@ -403,8 +403,10 @@
    * Application data must come in the encrypted epoch, and ChangeCipherSpec in
    * the unencrypted epoch (we never renegotiate). Other cases fall through and
    * fail with a fatal error. */
-  if ((rr->type == SSL3_RT_APPLICATION_DATA && ssl->aead_read_ctx != NULL) ||
-      (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC && ssl->aead_read_ctx == NULL)) {
+  if ((rr->type == SSL3_RT_APPLICATION_DATA &&
+       ssl->s3->aead_read_ctx != NULL) ||
+      (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC &&
+       ssl->s3->aead_read_ctx == NULL)) {
     rr->length = 0;
     goto start;
   }
diff --git a/ssl/dtls_record.c b/ssl/dtls_record.c
index af839ca..eaf6df7 100644
--- a/ssl/dtls_record.c
+++ b/ssl/dtls_record.c
@@ -213,7 +213,7 @@
 
   /* Decrypt the body. */
   size_t plaintext_len;
-  if (!SSL_AEAD_CTX_open(ssl->aead_read_ctx, out, &plaintext_len, max_out,
+  if (!SSL_AEAD_CTX_open(ssl->s3->aead_read_ctx, out, &plaintext_len, max_out,
                          type, version, sequence, CBS_data(&body),
                          CBS_len(&body))) {
     /* Bad packets are silently dropped in DTLS. See section 4.2.1 of RFC 6347.
@@ -250,7 +250,7 @@
                      enum dtls1_use_epoch_t use_epoch) {
   /* Determine the parameters for the current epoch. */
   uint16_t epoch = ssl->d1->w_epoch;
-  SSL_AEAD_CTX *aead = ssl->aead_write_ctx;
+  SSL_AEAD_CTX *aead = ssl->s3->aead_write_ctx;
   uint8_t *seq = ssl->s3->write_sequence;
   if (use_epoch == dtls1_use_previous_epoch) {
     /* DTLS renegotiation is unsupported, so only epochs 0 (NULL cipher) and 1
diff --git a/ssl/internal.h b/ssl/internal.h
index 110a5ba..58dca0f 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -981,7 +981,6 @@
 extern const SSL3_ENC_METHOD SSLv3_enc_data;
 extern const SRTP_PROTECTION_PROFILE kSRTPProfiles[];
 
-void ssl_clear_cipher_ctx(SSL *ssl);
 int ssl_clear_bad_session(SSL *ssl);
 CERT *ssl_cert_new(void);
 CERT *ssl_cert_dup(CERT *cert);
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 7ff0a15..b7696e7 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -1966,7 +1966,7 @@
   assert(ssl->state == SSL3_ST_CW_NEXT_PROTO_A);
 
   static const uint8_t kZero[32] = {0};
-  size_t padding_len = 32 - ((ssl->next_proto_negotiated_len + 2) % 32);
+  size_t padding_len = 32 - ((ssl->s3->next_proto_negotiated_len + 2) % 32);
 
   CBB cbb, child;
   size_t length;
@@ -1974,8 +1974,8 @@
   if (!CBB_init_fixed(&cbb, ssl_handshake_start(ssl),
                       ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl)) ||
       !CBB_add_u8_length_prefixed(&cbb, &child) ||
-      !CBB_add_bytes(&child, ssl->next_proto_negotiated,
-                     ssl->next_proto_negotiated_len) ||
+      !CBB_add_bytes(&child, ssl->s3->next_proto_negotiated,
+                     ssl->s3->next_proto_negotiated_len) ||
       !CBB_add_u8_length_prefixed(&cbb, &child) ||
       !CBB_add_bytes(&child, kZero, padding_len) ||
       !CBB_finish(&cbb, NULL, &length) ||
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index a84227d..6b132ed 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -237,7 +237,10 @@
   OPENSSL_free(ssl->s3->tmp.peer_psk_identity_hint);
   ssl3_free_handshake_buffer(ssl);
   ssl3_free_handshake_hash(ssl);
+  OPENSSL_free(ssl->s3->next_proto_negotiated);
   OPENSSL_free(ssl->s3->alpn_selected);
+  SSL_AEAD_CTX_free(ssl->s3->aead_read_ctx);
+  SSL_AEAD_CTX_free(ssl->s3->aead_write_ctx);
 
   OPENSSL_cleanse(ssl->s3, sizeof *ssl->s3);
   OPENSSL_free(ssl->s3);
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index b4cc725..51084d3 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -437,7 +437,7 @@
     /* Make sure that we are not getting application data when we are doing a
      * handshake for the first time. */
     if (SSL_in_init(ssl) && type == SSL3_RT_APPLICATION_DATA &&
-        ssl->aead_read_ctx == NULL) {
+        ssl->s3->aead_read_ctx == NULL) {
       /* TODO(davidben): Is this check redundant with the handshake_func
        * check? */
       al = SSL_AD_UNEXPECTED_MESSAGE;
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index 8f1899d..c0b2d80 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -2150,8 +2150,8 @@
   if (!CBS_get_u8_length_prefixed(&next_protocol, &selected_protocol) ||
       !CBS_get_u8_length_prefixed(&next_protocol, &padding) ||
       CBS_len(&next_protocol) != 0 ||
-      !CBS_stow(&selected_protocol, &ssl->next_proto_negotiated,
-                &ssl->next_proto_negotiated_len)) {
+      !CBS_stow(&selected_protocol, &ssl->s3->next_proto_negotiated,
+                &ssl->s3->next_proto_negotiated_len)) {
     return 0;
   }
 
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 8c09031..6b9e6ba 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -486,8 +486,6 @@
   ssl_clear_bad_session(ssl);
   SSL_SESSION_free(ssl->session);
 
-  ssl_clear_cipher_ctx(ssl);
-
   ssl_cert_free(ssl->cert);
 
   OPENSSL_free(ssl->tlsext_hostname);
@@ -497,7 +495,6 @@
   EVP_PKEY_free(ssl->tlsext_channel_id_private);
   OPENSSL_free(ssl->psk_identity_hint);
   sk_X509_NAME_pop_free(ssl->client_CA, X509_NAME_free);
-  OPENSSL_free(ssl->next_proto_negotiated);
   sk_SRTP_PROTECTION_PROFILE_free(ssl->srtp_profiles);
 
   if (ssl->method != NULL) {
@@ -513,8 +510,6 @@
   ssl->shutdown = 0;
   ssl->state = SSL_ST_CONNECT;
   ssl->handshake_func = ssl->method->ssl_connect;
-  /* clear the current cipher */
-  ssl_clear_cipher_ctx(ssl);
 }
 
 void SSL_set_accept_state(SSL *ssl) {
@@ -522,8 +517,6 @@
   ssl->shutdown = 0;
   ssl->state = SSL_ST_ACCEPT;
   ssl->handshake_func = ssl->method->ssl_accept;
-  /* clear the current cipher */
-  ssl_clear_cipher_ctx(ssl);
 }
 
 void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio) {
@@ -1574,11 +1567,11 @@
 
 void SSL_get0_next_proto_negotiated(const SSL *ssl, const uint8_t **out_data,
                                     unsigned *out_len) {
-  *out_data = ssl->next_proto_negotiated;
+  *out_data = ssl->s3->next_proto_negotiated;
   if (*out_data == NULL) {
     *out_len = 0;
   } else {
-    *out_len = ssl->next_proto_negotiated_len;
+    *out_len = ssl->s3->next_proto_negotiated_len;
   }
 }
 
@@ -1822,13 +1815,6 @@
   return ssl_get_version(session->ssl_version);
 }
 
-void ssl_clear_cipher_ctx(SSL *ssl) {
-  SSL_AEAD_CTX_free(ssl->aead_read_ctx);
-  ssl->aead_read_ctx = NULL;
-  SSL_AEAD_CTX_free(ssl->aead_write_ctx);
-  ssl->aead_write_ctx = NULL;
-}
-
 X509 *SSL_get_certificate(const SSL *ssl) {
   if (ssl->cert != NULL) {
     return ssl->cert->x509;
@@ -1862,10 +1848,10 @@
 }
 
 const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl) {
-  if (ssl->aead_write_ctx == NULL) {
+  if (ssl->s3->aead_write_ctx == NULL) {
     return NULL;
   }
-  return ssl->aead_write_ctx->cipher;
+  return ssl->s3->aead_write_ctx->cipher;
 }
 
 const COMP_METHOD *SSL_get_current_compression(SSL *ssl) { return NULL; }
@@ -2541,23 +2527,24 @@
 
 int SSL_get_rc4_state(const SSL *ssl, const RC4_KEY **read_key,
                       const RC4_KEY **write_key) {
-  if (ssl->aead_read_ctx == NULL || ssl->aead_write_ctx == NULL) {
+  if (ssl->s3->aead_read_ctx == NULL || ssl->s3->aead_write_ctx == NULL) {
     return 0;
   }
 
-  return EVP_AEAD_CTX_get_rc4_state(&ssl->aead_read_ctx->ctx, read_key) &&
-         EVP_AEAD_CTX_get_rc4_state(&ssl->aead_write_ctx->ctx, write_key);
+  return EVP_AEAD_CTX_get_rc4_state(&ssl->s3->aead_read_ctx->ctx, read_key) &&
+         EVP_AEAD_CTX_get_rc4_state(&ssl->s3->aead_write_ctx->ctx, write_key);
 }
 
 int SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv,
                 const uint8_t **out_write_iv, size_t *out_iv_len) {
-  if (ssl->aead_read_ctx == NULL || ssl->aead_write_ctx == NULL) {
+  if (ssl->s3->aead_read_ctx == NULL || ssl->s3->aead_write_ctx == NULL) {
     return 0;
   }
 
   size_t write_iv_len;
-  if (!EVP_AEAD_CTX_get_iv(&ssl->aead_read_ctx->ctx, out_read_iv, out_iv_len) ||
-      !EVP_AEAD_CTX_get_iv(&ssl->aead_write_ctx->ctx, out_write_iv,
+  if (!EVP_AEAD_CTX_get_iv(&ssl->s3->aead_read_ctx->ctx, out_read_iv,
+                           out_iv_len) ||
+      !EVP_AEAD_CTX_get_iv(&ssl->s3->aead_write_ctx->ctx, out_write_iv,
                            &write_iv_len) ||
       *out_iv_len != write_iv_len) {
     return 0;
@@ -2630,12 +2617,6 @@
   BUF_MEM_free(ssl->init_buf);
   ssl->init_buf = NULL;
 
-  ssl_clear_cipher_ctx(ssl);
-
-  OPENSSL_free(ssl->next_proto_negotiated);
-  ssl->next_proto_negotiated = NULL;
-  ssl->next_proto_negotiated_len = 0;
-
   /* The ssl->d1->mtu is simultaneously configuration (preserved across
    * clear) and connection-specific state (gets reset).
    *
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 25d9916..2d0a4fb 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -1311,14 +1311,14 @@
     return 0;
   }
 
-  OPENSSL_free(ssl->next_proto_negotiated);
-  ssl->next_proto_negotiated = BUF_memdup(selected, selected_len);
-  if (ssl->next_proto_negotiated == NULL) {
+  OPENSSL_free(ssl->s3->next_proto_negotiated);
+  ssl->s3->next_proto_negotiated = BUF_memdup(selected, selected_len);
+  if (ssl->s3->next_proto_negotiated == NULL) {
     *out_alert = SSL_AD_INTERNAL_ERROR;
     return 0;
   }
 
-  ssl->next_proto_negotiated_len = selected_len;
+  ssl->s3->next_proto_negotiated_len = selected_len;
   ssl->s3->next_proto_neg_seen = 1;
 
   return 1;
diff --git a/ssl/tls_record.c b/ssl/tls_record.c
index 0f29321..25d6e82 100644
--- a/ssl/tls_record.c
+++ b/ssl/tls_record.c
@@ -126,9 +126,9 @@
 /* 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 &&
+  return !SSL_USE_EXPLICIT_IV(ssl) && ssl->s3->aead_write_ctx != NULL &&
          (ssl->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0 &&
-         SSL_CIPHER_is_block_cipher(ssl->aead_write_ctx->cipher);
+         SSL_CIPHER_is_block_cipher(ssl->s3->aead_write_ctx->cipher);
 }
 
 int ssl_record_sequence_update(uint8_t *seq, size_t seq_len) {
@@ -146,23 +146,23 @@
 size_t ssl_record_prefix_len(const SSL *ssl) {
   if (SSL_IS_DTLS(ssl)) {
     return DTLS1_RT_HEADER_LENGTH +
-           SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_read_ctx);
+           SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->aead_read_ctx);
   } else {
     return SSL3_RT_HEADER_LENGTH +
-           SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_read_ctx);
+           SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->aead_read_ctx);
   }
 }
 
 size_t ssl_seal_prefix_len(const SSL *ssl) {
   if (SSL_IS_DTLS(ssl)) {
     return DTLS1_RT_HEADER_LENGTH +
-           SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_write_ctx);
+           SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->aead_write_ctx);
   } else {
     size_t ret = SSL3_RT_HEADER_LENGTH +
-                 SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_write_ctx);
+                 SSL_AEAD_CTX_explicit_nonce_len(ssl->s3->aead_write_ctx);
     if (ssl_needs_record_splitting(ssl)) {
       ret += SSL3_RT_HEADER_LENGTH;
-      ret += ssl_cipher_get_record_split_len(ssl->aead_write_ctx->cipher);
+      ret += ssl_cipher_get_record_split_len(ssl->s3->aead_write_ctx->cipher);
     }
     return ret;
   }
@@ -171,10 +171,10 @@
 size_t ssl_max_seal_overhead(const SSL *ssl) {
   if (SSL_IS_DTLS(ssl)) {
     return DTLS1_RT_HEADER_LENGTH +
-           SSL_AEAD_CTX_max_overhead(ssl->aead_write_ctx);
+           SSL_AEAD_CTX_max_overhead(ssl->s3->aead_write_ctx);
   } else {
     size_t ret = SSL3_RT_HEADER_LENGTH +
-                 SSL_AEAD_CTX_max_overhead(ssl->aead_write_ctx);
+                 SSL_AEAD_CTX_max_overhead(ssl->s3->aead_write_ctx);
     if (ssl_needs_record_splitting(ssl)) {
       ret *= 2;
     }
@@ -228,7 +228,7 @@
 
   /* Decrypt the body. */
   size_t plaintext_len;
-  if (!SSL_AEAD_CTX_open(ssl->aead_read_ctx, out, &plaintext_len, max_out,
+  if (!SSL_AEAD_CTX_open(ssl->s3->aead_read_ctx, out, &plaintext_len, max_out,
                          type, version, ssl->s3->read_sequence, CBS_data(&body),
                          CBS_len(&body))) {
     OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
@@ -293,7 +293,7 @@
   out[2] = wire_version & 0xff;
 
   size_t ciphertext_len;
-  if (!SSL_AEAD_CTX_seal(ssl->aead_write_ctx, out + SSL3_RT_HEADER_LENGTH,
+  if (!SSL_AEAD_CTX_seal(ssl->s3->aead_write_ctx, out + SSL3_RT_HEADER_LENGTH,
                          &ciphertext_len, max_out - SSL3_RT_HEADER_LENGTH,
                          type, wire_version, ssl->s3->write_sequence, in,
                          in_len) ||
@@ -342,8 +342,8 @@
     out += frag_len;
     max_out -= frag_len;
 
-    assert(SSL3_RT_HEADER_LENGTH +
-               ssl_cipher_get_record_split_len(ssl->aead_write_ctx->cipher) ==
+    assert(SSL3_RT_HEADER_LENGTH + ssl_cipher_get_record_split_len(
+                                       ssl->s3->aead_write_ctx->cipher) ==
            frag_len);
   }
 
@@ -361,8 +361,8 @@
   }
   memset(ssl->s3->read_sequence, 0, sizeof(ssl->s3->read_sequence));
 
-  SSL_AEAD_CTX_free(ssl->aead_read_ctx);
-  ssl->aead_read_ctx = aead_ctx;
+  SSL_AEAD_CTX_free(ssl->s3->aead_read_ctx);
+  ssl->s3->aead_read_ctx = aead_ctx;
 }
 
 void ssl_set_write_state(SSL *ssl, SSL_AEAD_CTX *aead_ctx) {
@@ -373,6 +373,6 @@
   }
   memset(ssl->s3->write_sequence, 0, sizeof(ssl->s3->write_sequence));
 
-  SSL_AEAD_CTX_free(ssl->aead_write_ctx);
-  ssl->aead_write_ctx = aead_ctx;
+  SSL_AEAD_CTX_free(ssl->s3->aead_write_ctx);
+  ssl->s3->aead_write_ctx = aead_ctx;
 }