Remove dead code from EVP_CIPHER codepaths.

Everything is an AEAD now.

Change-Id: Ib47638e128843fc8299c3dbf9bd60c01eb5afa16
Reviewed-on: https://boringssl-review.googlesource.com/2700
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 1404be0..e954038 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -1259,19 +1259,8 @@
 	struct ssl_cipher_preference_list_st *cipher_list;
 	STACK_OF(SSL_CIPHER) *cipher_list_by_id;
 
-	/* These are the ones being used, the ones in SSL_SESSION are
-	 * the ones to be 'copied' into these ones */
-	SSL_AEAD_CTX *aead_read_ctx;	/* AEAD context. If non-NULL, then
-					   |enc_read_ctx| and |read_hash| are
-					   ignored. */
-	EVP_CIPHER_CTX *enc_read_ctx;		/* cryptographic state */
-	EVP_MD_CTX *read_hash;		/* used for mac generation */
-
-	SSL_AEAD_CTX *aead_write_ctx;	/* AEAD context. If non-NULL, then
-					   |enc_write_ctx| and |write_hash| are
-					   ignored. */
-	EVP_CIPHER_CTX *enc_write_ctx;		/* cryptographic state */
-	EVP_MD_CTX *write_hash;		/* used for mac generation */
+	SSL_AEAD_CTX *aead_read_ctx;
+	SSL_AEAD_CTX *aead_write_ctx;
 
 	/* session info */
 
diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h
index ae6c52c..c502b5a 100644
--- a/include/openssl/ssl3.h
+++ b/include/openssl/ssl3.h
@@ -464,10 +464,7 @@
 		int key_block_length;
 		unsigned char *key_block;
 
-		const EVP_CIPHER *new_sym_enc;
 		const EVP_AEAD *new_aead;
-		const EVP_MD *new_hash;
-		int new_mac_pkey_type;
 		uint8_t new_mac_secret_len;
 		uint8_t new_fixed_iv_len;
 		uint8_t new_variable_iv_len;
diff --git a/ssl/CMakeLists.txt b/ssl/CMakeLists.txt
index 3852d20..954418b 100644
--- a/ssl/CMakeLists.txt
+++ b/ssl/CMakeLists.txt
@@ -14,7 +14,6 @@
 	d1_srtp.c
 	d1_srvr.c
 	s3_both.c
-	s3_cbc.c
 	s3_clnt.c
 	s3_enc.c
 	s3_lib.c
diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c
index e4928a5..9fcc050 100644
--- a/ssl/d1_lib.c
+++ b/ssl/d1_lib.c
@@ -78,7 +78,6 @@
 
 const SSL3_ENC_METHOD DTLSv1_enc_data = {
   tls1_enc,
-  tls1_mac,
   tls1_prf,
   tls1_setup_key_block,
   tls1_generate_master_secret,
@@ -98,7 +97,6 @@
 
 const SSL3_ENC_METHOD DTLSv1_2_enc_data = {
   tls1_enc,
-  tls1_mac,
   tls1_prf,
   tls1_setup_key_block,
   tls1_generate_master_secret,
diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c
index 85bd305..451a3c2 100644
--- a/ssl/d1_pkt.c
+++ b/ssl/d1_pkt.c
@@ -328,15 +328,11 @@
 }
 
 static int dtls1_process_record(SSL *s) {
-  int i, al;
+  int al;
   int enc_err;
-  SSL_SESSION *sess;
   SSL3_RECORD *rr;
-  unsigned int mac_size, orig_len;
-  unsigned char md[EVP_MAX_MD_SIZE];
 
   rr = &(s->s3->rrec);
-  sess = s->session;
 
   /* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, and
    * we have that many bytes in s->packet. */
@@ -372,55 +368,6 @@
     s->packet_length = 0;
     goto err;
   }
-
-  /* r->length is now the compressed data plus mac */
-  if ((sess != NULL) && (s->enc_read_ctx != NULL) &&
-      (EVP_MD_CTX_md(s->read_hash) != NULL)) {
-    /* s->read_hash != NULL => mac_size != -1 */
-    uint8_t *mac = NULL;
-    uint8_t mac_tmp[EVP_MAX_MD_SIZE];
-    mac_size = EVP_MD_CTX_size(s->read_hash);
-    assert(mac_size <= EVP_MAX_MD_SIZE);
-
-    /* kludge: *_cbc_remove_padding passes padding length in rr->type */
-    orig_len = rr->length + ((unsigned int)rr->type >> 8);
-
-    /* orig_len is the length of the record before any padding was removed.
-     * This is public information, as is the MAC in use, therefore we can
-     * safely process the record in a different amount of time if it's too
-     * short to possibly contain a MAC. */
-    if (orig_len < mac_size ||
-        /* CBC records must have a padding length byte too. */
-        (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
-         orig_len < mac_size + 1)) {
-      al = SSL_AD_DECODE_ERROR;
-      OPENSSL_PUT_ERROR(SSL, dtls1_process_record, SSL_R_LENGTH_TOO_SHORT);
-      goto f_err;
-    }
-
-    if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) {
-      /* We update the length so that the TLS header bytes can be constructed
-       * correctly but we need to extract the MAC in constant time from within
-       * the record, without leaking the contents of the padding bytes. */
-      mac = mac_tmp;
-      ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len);
-      rr->length -= mac_size;
-    } else {
-      /* In this case there's no padding, so |orig_len| equals |rec->length|
-       * and we checked that there's enough bytes for |mac_size| above. */
-      rr->length -= mac_size;
-      mac = &rr->data[rr->length];
-    }
-
-    i = s->enc_method->mac(s, md, 0 /* not send */);
-    if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) {
-      enc_err = -1;
-    }
-    if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size) {
-      enc_err = -1;
-    }
-  }
-
   if (enc_err < 0) {
     /* decryption failed, silently discard message */
     rr->length = 0;
@@ -761,7 +708,9 @@
     /* make sure that we are not getting application data when we
      * are doing a handshake for the first time */
     if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&
-        (s->enc_read_ctx == NULL)) {
+        (s->aead_read_ctx == NULL)) {
+      /* TODO(davidben): Is this check redundant with the handshake_func
+       * check? */
       al = SSL_AD_UNEXPECTED_MESSAGE;
       OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_APP_DATA_IN_HANDSHAKE);
       goto f_err;
@@ -1151,12 +1100,11 @@
 static int do_dtls1_write(SSL *s, int type, const uint8_t *buf,
                           unsigned int len) {
   uint8_t *p, *pseq;
-  int i, mac_size = 0;
+  int i;
   int prefix_len = 0;
   int eivlen = 0;
   SSL3_RECORD *wr;
   SSL3_BUFFER *wb;
-  SSL_SESSION *sess;
 
   /* first check if there is a SSL3_BUFFER still being written
    * out.  This will happen with non blocking IO */
@@ -1180,15 +1128,6 @@
 
   wr = &(s->s3->wrec);
   wb = &(s->s3->wbuf);
-  sess = s->session;
-
-  if (sess != NULL && s->enc_write_ctx != NULL &&
-      EVP_MD_CTX_md(s->write_hash) != NULL) {
-    mac_size = EVP_MD_CTX_size(s->write_hash);
-    if (mac_size < 0) {
-      goto err;
-    }
-  }
 
   p = wb->buf + prefix_len;
 
@@ -1212,15 +1151,9 @@
   pseq = p;
   p += 10;
 
-  /* Explicit IV length, block ciphers appropriate version flag */
-  if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s) &&
-      EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_CBC_MODE) {
-    eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx);
-    if (eivlen <= 1) {
-      eivlen = 0;
-    }
-  } else if (s->aead_write_ctx != NULL &&
-             s->aead_write_ctx->variable_nonce_included_in_record) {
+  /* Leave room for the variable nonce for AEADs which specify it explicitly. */
+  if (s->aead_write_ctx != NULL &&
+      s->aead_write_ctx->variable_nonce_included_in_record) {
     eivlen = s->aead_write_ctx->variable_nonce_len;
   }
 
@@ -1233,15 +1166,6 @@
   memcpy(wr->data, wr->input, wr->length);
   wr->input = wr->data;
 
-  /* we should still have the output to wr->data and the input from wr->input.
-   * Length should be wr->length. wr->data still points in the wb->buf */
-  if (mac_size != 0) {
-    if (s->enc_method->mac(s, &(p[wr->length + eivlen]), 1) < 0) {
-      goto err;
-    }
-    wr->length += mac_size;
-  }
-
   /* this is true regardless of mac size */
   wr->input = p;
   wr->data = p;
diff --git a/ssl/s3_cbc.c b/ssl/s3_cbc.c
deleted file mode 100644
index 418a04f..0000000
--- a/ssl/s3_cbc.c
+++ /dev/null
@@ -1,601 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2012 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com). */
-
-#include <assert.h>
-
-#include <openssl/obj.h>
-#include <openssl/sha.h>
-
-#include "../crypto/internal.h"
-#include "ssl_locl.h"
-
-
-/* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length
- * field. (SHA-384/512 have 128-bit length.) */
-#define MAX_HASH_BIT_COUNT_BYTES 16
-
-/* MAX_HASH_BLOCK_SIZE is the maximum hash block size that we'll support.
- * Currently SHA-384/512 has a 128-byte block size and that's the largest
- * supported by TLS.) */
-#define MAX_HASH_BLOCK_SIZE 128
-
-/* ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC
- * record in |rec| by updating |rec->length| in constant time.
- *
- * 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 ssl3_cbc_remove_padding(const SSL *s, SSL3_RECORD *rec, 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 > rec->length) {
-    return 0;
-  }
-
-  padding_length = rec->data[rec->length - 1];
-  good = constant_time_ge(rec->length, 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);
-  rec->length -= padding_length;
-  rec->type |= padding_length << 8; /* kludge: pass padding length */
-  return constant_time_select_int(good, 1, -1);
-}
-
-/* tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC
- * record in |rec| in constant time and returns 1 if the padding is valid and
- * -1 otherwise. It also removes any explicit IV from the start of the record
- * without leaking any timing about whether there was enough space after the
- * padding was removed.
- *
- * 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 tls1_cbc_remove_padding(const SSL *s, SSL3_RECORD *rec, unsigned block_size,
-                            unsigned mac_size) {
-  unsigned padding_length, good, to_check, i;
-  const unsigned overhead = 1 /* padding length byte */ + mac_size;
-
-  /* Check if version requires explicit IV */
-  if (SSL_USE_EXPLICIT_IV(s)) {
-    /* These lengths are all public so we can test them in
-     * non-constant time. */
-    if (overhead + block_size > rec->length) {
-      return 0;
-    }
-    /* We can now safely skip explicit IV */
-    rec->data += block_size;
-    rec->input += block_size;
-    rec->length -= block_size;
-  } else if (overhead > rec->length) {
-    return 0;
-  }
-
-  padding_length = rec->data[rec->length - 1];
-
-  good = constant_time_ge(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 byte. Thus, with the length byte included, there are i+1
-   * bytes of padding.
-   *
-   * We can't check just |padding_length+1| bytes because that leaks
-   * decrypted information. Therefore we always have to check the maximum
-   * amount of padding possible. (Again, the length of the record is
-   * public information so we can use it.) */
-  to_check = 256; /* maximum amount of padding, inc length byte. */
-  if (to_check > rec->length) {
-    to_check = rec->length;
-  }
-
-  for (i = 0; i < to_check; i++) {
-    unsigned char mask = constant_time_ge_8(padding_length, i);
-    unsigned char b = rec->data[rec->length - 1 - i];
-    /* The final |padding_length+1| bytes should all have the value
-     * |padding_length|. Therefore the XOR should be zero. */
-    good &= ~(mask & (padding_length ^ b));
-  }
-
-  /* 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);
-
-  padding_length = good & (padding_length + 1);
-  rec->length -= padding_length;
-  rec->type |= padding_length << 8; /* kludge: pass padding length */
-
-  return constant_time_select_int(good, 1, -1);
-}
-
-/* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in
- * constant time (independent of the concrete value of rec->length, which may
- * vary within a 256-byte window).
- *
- * ssl3_cbc_remove_padding or tls1_cbc_remove_padding must be called prior to
- * this function.
- *
- * On entry:
- *   rec->orig_len >= md_size
- *   md_size <= EVP_MAX_MD_SIZE
- *
- * If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation 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 ssl3_cbc_copy_mac(unsigned char *out, const SSL3_RECORD *rec,
-                       unsigned md_size, unsigned orig_len) {
-#if defined(CBC_MAC_ROTATE_IN_PLACE)
-  unsigned char rotated_mac_buf[64 + EVP_MAX_MD_SIZE];
-  unsigned char *rotated_mac;
-#else
-  unsigned char rotated_mac[EVP_MAX_MD_SIZE];
-#endif
-
-  /* mac_end is the index of |rec->data| just after the end of the MAC. */
-  unsigned mac_end = rec->length;
-  unsigned mac_start = mac_end - md_size;
-  /* scan_start contains the number of bytes that we can ignore because
-   * the MAC's position can only vary by 255 bytes. */
-  unsigned scan_start = 0;
-  unsigned i, j;
-  unsigned div_spoiler;
-  unsigned rotate_offset;
-
-  assert(orig_len >= md_size);
-  assert(md_size <= EVP_MAX_MD_SIZE);
-
-#if defined(CBC_MAC_ROTATE_IN_PLACE)
-  rotated_mac = rotated_mac_buf + ((0 - (size_t)rotated_mac_buf) & 63);
-#endif
-
-  /* This information is public so it's safe to branch based on it. */
-  if (orig_len > md_size + 255 + 1) {
-    scan_start = orig_len - (md_size + 255 + 1);
-  }
-  /* div_spoiler contains a multiple of md_size that is used to cause the
-   * modulo operation to be constant time. Without this, the time varies
-   * based on the amount of padding when running on Intel chips at least.
-   *
-   * The aim of right-shifting md_size is so that the compiler doesn't
-   * figure out that it can remove div_spoiler as that would require it
-   * to prove that md_size is always even, which I hope is beyond it. */
-  div_spoiler = md_size >> 1;
-  div_spoiler <<= (sizeof(div_spoiler) - 1) * 8;
-  rotate_offset = (div_spoiler + mac_start - scan_start) % md_size;
-
-  memset(rotated_mac, 0, md_size);
-  for (i = scan_start, j = 0; i < 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 b = rec->data[i];
-    rotated_mac[j++] |= b & mac_started & ~mac_ended;
-    j &= constant_time_lt(j, md_size);
-  }
-
-/* Now rotate the MAC */
-#if defined(CBC_MAC_ROTATE_IN_PLACE)
-  j = 0;
-  for (i = 0; i < md_size; i++) {
-    /* 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);
-  }
-#else
-  memset(out, 0, md_size);
-  rotate_offset = md_size - rotate_offset;
-  rotate_offset &= constant_time_lt(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);
-    }
-    rotate_offset++;
-    rotate_offset &= constant_time_lt(rotate_offset, md_size);
-  }
-#endif
-}
-
-/* u32toLE serialises an unsigned, 32-bit number (n) as four bytes at (p) in
- * little-endian order. The value of p is advanced by four. */
-#define u32toLE(n, p) \
-  (*((p)++)=(unsigned char)(n), \
-   *((p)++)=(unsigned char)(n>>8), \
-   *((p)++)=(unsigned char)(n>>16), \
-   *((p)++)=(unsigned char)(n>>24))
-
-/* These functions serialize the state of a hash and thus perform the standard
- * "final" operation without adding the padding and length that such a function
- * typically does. */
-static void tls1_sha1_final_raw(void *ctx, unsigned char *md_out) {
-  SHA_CTX *sha1 = ctx;
-  l2n(sha1->h0, md_out);
-  l2n(sha1->h1, md_out);
-  l2n(sha1->h2, md_out);
-  l2n(sha1->h3, md_out);
-  l2n(sha1->h4, md_out);
-}
-#define LARGEST_DIGEST_CTX SHA_CTX
-
-static void tls1_sha256_final_raw(void *ctx, unsigned char *md_out) {
-  SHA256_CTX *sha256 = ctx;
-  unsigned i;
-
-  for (i = 0; i < 8; i++) {
-    l2n(sha256->h[i], md_out);
-  }
-}
-#undef  LARGEST_DIGEST_CTX
-#define LARGEST_DIGEST_CTX SHA256_CTX
-
-static void tls1_sha512_final_raw(void *ctx, unsigned char *md_out) {
-  SHA512_CTX *sha512 = ctx;
-  unsigned i;
-
-  for (i = 0; i < 8; i++) {
-    l2n8(sha512->h[i], md_out);
-  }
-}
-#undef  LARGEST_DIGEST_CTX
-#define LARGEST_DIGEST_CTX SHA512_CTX
-
-/* ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function
- * which ssl3_cbc_digest_record supports. */
-char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx) {
-  switch (EVP_MD_CTX_type(ctx)) {
-    case NID_sha1:
-    case NID_sha256:
-    case NID_sha384:
-      return 1;
-
-    default:
-      return 0;
-  }
-}
-
-/* ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS
- * record.
- *
- *   ctx: the EVP_MD_CTX from which we take the hash function.
- *     ssl3_cbc_record_digest_supported must return true for this EVP_MD_CTX.
- *   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.
- *   data: the record data itself, less any preceeding explicit IV.
- *   data_plus_mac_size: the secret, reported length of the data and MAC
- *     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 ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, unsigned char *md_out,
-                           size_t *md_out_size, const unsigned char header[13],
-                           const unsigned char *data, size_t data_plus_mac_size,
-                           size_t data_plus_mac_plus_padding_size,
-                           const unsigned char *mac_secret,
-                           unsigned mac_secret_length, char is_sslv3) {
-  union {
-    double align;
-    unsigned char c[sizeof(LARGEST_DIGEST_CTX)];
-  } md_state;
-  void (*md_final_raw)(void *ctx, unsigned char *md_out);
-  void (*md_transform)(void *ctx, const unsigned char *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 int bits; /* at most 18 bits */
-  unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES];
-  /* hmac_pad is the masked HMAC key. */
-  unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE];
-  unsigned char first_block[MAX_HASH_BLOCK_SIZE];
-  unsigned char mac_out[EVP_MAX_MD_SIZE];
-  unsigned i, j, md_out_size_u;
-  EVP_MD_CTX md_ctx;
-  /* mdLengthSize is the number of bytes in the length field that terminates
-  * the hash. */
-  unsigned md_length_size = 8;
-
-  /* This is a, hopefully redundant, check that allows us to forget about
-   * many possible overflows later in this function. */
-  assert(data_plus_mac_plus_padding_size < 1024 * 1024);
-
-  switch (EVP_MD_CTX_type(ctx)) {
-    case NID_sha1:
-      SHA1_Init((SHA_CTX *)md_state.c);
-      md_final_raw = tls1_sha1_final_raw;
-      md_transform =
-          (void (*)(void *ctx, const unsigned char *block))SHA1_Transform;
-      md_size = 20;
-      break;
-
-    case NID_sha256:
-      SHA256_Init((SHA256_CTX *)md_state.c);
-      md_final_raw = tls1_sha256_final_raw;
-      md_transform =
-          (void (*)(void *ctx, const unsigned char *block))SHA256_Transform;
-      md_size = 32;
-      break;
-
-    case NID_sha384:
-      SHA384_Init((SHA512_CTX *)md_state.c);
-      md_final_raw = tls1_sha512_final_raw;
-      md_transform =
-          (void (*)(void *ctx, const unsigned char *block))SHA512_Transform;
-      md_size = 384 / 8;
-      md_block_size = 128;
-      md_length_size = 16;
-      break;
-
-    default:
-      /* ssl3_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;
-  }
-
-  assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES);
-  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 */;
-  }
-
-  /* variance_blocks 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;
-  /* 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;
-  /* 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;
-  /* num_blocks is the maximum number of hash blocks. */
-  num_blocks =
-      (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
-   * 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. */
-  num_starting_blocks = 0;
-  /* k is the starting byte offset into the conceptual header||data where
-   * we start processing. */
-  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;
-  /* c is the index of the 0x80 byte in the final hash block that
-   * contains application data. */
-  c = mac_end_offset % md_block_size;
-  /* index_a is the hash block number that contains the 0x80 terminating
-   * value. */
-  index_a = mac_end_offset / md_block_size;
-  /* index_b is the hash block number that contains the 64-bit hash
-   * 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. */
-
-  /* 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;
-    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);
-  }
-
-  memset(length_bytes, 0, md_length_size - 4);
-  length_bytes[md_length_size - 4] = (unsigned char)(bits >> 24);
-  length_bytes[md_length_size - 3] = (unsigned char)(bits >> 16);
-  length_bytes[md_length_size - 2] = (unsigned char)(bits >> 8);
-  length_bytes[md_length_size - 1] = (unsigned char)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);
-      }
-    }
-  }
-
-  memset(mac_out, 0, sizeof(mac_out));
-
-  /* We now process the final hash blocks. For each block, we construct
-   * 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;
-       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);
-    for (j = 0; j < md_block_size; j++) {
-      unsigned char b = 0, is_past_c, is_past_cp1;
-      if (k < header_length) {
-        b = header[k];
-      } else if (k < data_plus_mac_plus_padding_size + header_length) {
-        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);
-      /* If this is the block containing the end of the
-       * application data, and we are at the offset for the
-       * 0x80 value, then overwrite b with 0x80. */
-      b = constant_time_select_8(is_past_c, 0x80, b);
-      /* If this the the block containing the end of the
-       * application data and we're past the 0x80 value then
-       * just write zero. */
-      b = b & ~is_past_cp1;
-      /* If this is index_b (the final block), but not
-       * index_a (the end of the data), then the 64-bit
-       * length didn't fit into index_a and we're having to
-       * add an extra block of zeros. */
-      b &= ~is_block_b | is_block_a;
-
-      /* The final bytes of one of the blocks contains the
-       * length. */
-      if (j >= md_block_size - md_length_size) {
-        /* If this is index_b, write a length byte. */
-        b = constant_time_select_8(
-            is_block_b, length_bytes[j - (md_block_size - md_length_size)], b);
-      }
-      block[j] = b;
-    }
-
-    md_transform(md_state.c, block);
-    md_final_raw(md_state.c, block);
-    /* If this is index_b, copy the hash value to |mac_out|. */
-    for (j = 0; j < md_size; j++) {
-      mac_out[j] |= block[j] & is_block_b;
-    }
-  }
-
-  EVP_MD_CTX_init(&md_ctx);
-  if (!EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */)) {
-    EVP_MD_CTX_cleanup(&md_ctx);
-    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);
-  }
-  EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u);
-  *md_out_size = md_out_size_u;
-  EVP_MD_CTX_cleanup(&md_ctx);
-
-  return 1;
-}
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 27bcc12..69a78e7 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -558,7 +558,6 @@
 
 const SSL3_ENC_METHOD SSLv3_enc_data = {
     tls1_enc,
-    tls1_mac,
     ssl3_prf,
     tls1_setup_key_block,
     tls1_generate_master_secret,
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index 95737a7..f51e829 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -270,16 +270,12 @@
   int ssl_major, ssl_minor, al;
   int enc_err, n, i, ret = -1;
   SSL3_RECORD *rr;
-  SSL_SESSION *sess;
   uint8_t *p;
-  uint8_t md[EVP_MAX_MD_SIZE];
   short version;
-  unsigned mac_size, orig_len;
   size_t extra;
   unsigned empty_record_count = 0;
 
   rr = &s->s3->rrec;
-  sess = s->session;
 
   if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) {
     extra = SSL3_RT_MAX_EXTRA;
@@ -387,55 +383,6 @@
     OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
     goto f_err;
   }
-
-  /* |r->length| is now the compressed data plus MAC. */
-  if (sess != NULL && s->enc_read_ctx != NULL &&
-      EVP_MD_CTX_md(s->read_hash) != NULL) {
-    /* s->read_hash != NULL => mac_size != -1 */
-    uint8_t *mac = NULL;
-    uint8_t mac_tmp[EVP_MAX_MD_SIZE];
-    mac_size = EVP_MD_CTX_size(s->read_hash);
-    assert(mac_size <= EVP_MAX_MD_SIZE);
-
-    /* kludge: *_cbc_remove_padding passes padding length in rr->type */
-    orig_len = rr->length + ((unsigned int)rr->type >> 8);
-
-    /* orig_len is the length of the record before any padding was removed.
-     * This is public information, as is the MAC in use, therefore we can
-     * safely process the record in a different amount of time if it's too
-     * short to possibly contain a MAC. */
-    if (orig_len < mac_size ||
-        /* CBC records must have a padding length byte too. */
-        (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
-         orig_len < mac_size + 1)) {
-      al = SSL_AD_DECODE_ERROR;
-      OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_LENGTH_TOO_SHORT);
-      goto f_err;
-    }
-
-    if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) {
-      /* We update the length so that the TLS header bytes can be constructed
-       * correctly but we need to extract the MAC in constant time from within
-       * the record, without leaking the contents of the padding bytes. */
-      mac = mac_tmp;
-      ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len);
-      rr->length -= mac_size;
-    } else {
-      /* In this case there's no padding, so |orig_len| equals |rec->length|
-       * and we checked that there's enough bytes for |mac_size| above. */
-      rr->length -= mac_size;
-      mac = &rr->data[rr->length];
-    }
-
-    i = s->enc_method->mac(s, md, 0 /* not send */);
-    if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) {
-      enc_err = -1;
-    }
-    if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + extra + mac_size) {
-      enc_err = -1;
-    }
-  }
-
   if (enc_err < 0) {
     /* A separate 'decryption_failed' alert was introduced with TLS 1.0, SSL
      * 3.0 only has 'bad_record_mac'.  But unless a decryption failure is
@@ -570,13 +517,12 @@
 static int do_ssl3_write(SSL *s, int type, const uint8_t *buf, unsigned int len,
                          char fragment, char is_fragment) {
   uint8_t *p, *plen;
-  int i, mac_size;
+  int i;
   int prefix_len = 0;
   int eivlen = 0;
   long align = 0;
   SSL3_RECORD *wr;
   SSL3_BUFFER *wb = &(s->s3->wbuf);
-  SSL_SESSION *sess;
 
   /* first check if there is a SSL3_BUFFER still being written out. This will
    * happen with non blocking IO */
@@ -602,17 +548,6 @@
   }
 
   wr = &s->s3->wrec;
-  sess = s->session;
-
-  if (sess == NULL || s->enc_write_ctx == NULL ||
-      EVP_MD_CTX_md(s->write_hash) == NULL) {
-    mac_size = 0;
-  } else {
-    mac_size = EVP_MD_CTX_size(s->write_hash);
-    if (mac_size < 0) {
-      goto err;
-    }
-  }
 
   if (fragment) {
     /* countermeasure against known-IV weakness in CBC ciphersuites (see
@@ -667,15 +602,9 @@
   plen = p;
   p += 2;
 
-  /* Explicit IV length, block ciphers appropriate version flag */
-  if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s) &&
-      EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_CBC_MODE) {
-    eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx);
-    if (eivlen <= 1) {
-      eivlen = 0;
-    }
-  } else if (s->aead_write_ctx != NULL &&
-             s->aead_write_ctx->variable_nonce_included_in_record) {
+  /* Leave room for the variable nonce for AEADs which specify it explicitly. */
+  if (s->aead_write_ctx != NULL &&
+      s->aead_write_ctx->variable_nonce_included_in_record) {
     eivlen = s->aead_write_ctx->variable_nonce_len;
   }
 
@@ -692,13 +621,6 @@
   /* we should still have the output to wr->data and the input from wr->input.
    * Length should be wr->length. wr->data still points in the wb->buf */
 
-  if (mac_size != 0) {
-    if (s->enc_method->mac(s, &(p[wr->length + eivlen]), 1) < 0) {
-      goto err;
-    }
-    wr->length += mac_size;
-  }
-
   wr->input = p;
   wr->data = p;
   wr->length += eivlen;
@@ -930,7 +852,9 @@
     /* make sure that we are not getting application data when we are doing a
      * handshake for the first time */
     if (SSL_in_init(s) && type == SSL3_RT_APPLICATION_DATA &&
-        s->enc_read_ctx == NULL) {
+        s->aead_read_ctx == NULL) {
+      /* TODO(davidben): Is this check redundant with the handshake_func
+       * check? */
       al = SSL_AD_UNEXPECTED_MESSAGE;
       OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_APP_DATA_IN_HANDSHAKE);
       goto f_err;
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index 3f164bd..55323d4 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -360,111 +360,6 @@
   }
 }
 
-int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
-                       const EVP_MD **md, int *mac_pkey_type,
-                       size_t *mac_secret_size) {
-  const SSL_CIPHER *c;
-
-  c = s->cipher;
-  if (c == NULL ||
-      /* This function doesn't deal with EVP_AEAD. See
-       * |ssl_cipher_get_aead_evp|. */
-      (c->algorithm2 & SSL_CIPHER_ALGORITHM2_AEAD) ||
-      enc == NULL ||
-      md == NULL) {
-    return 0;
-  }
-
-  switch (c->algorithm_enc) {
-    case SSL_3DES:
-      *enc = EVP_des_ede3_cbc();
-      break;
-
-    case SSL_RC4:
-      *enc = EVP_rc4();
-      break;
-
-    case SSL_AES128:
-      *enc = EVP_aes_128_cbc();
-      break;
-
-    case SSL_AES256:
-      *enc = EVP_aes_256_cbc();
-      break;
-
-    default:
-      return 0;
-  }
-
-  if (!ssl_cipher_get_mac(s, md, mac_pkey_type, mac_secret_size)) {
-    return 0;
-  }
-
-  assert(*enc != NULL && *md != NULL);
-
-/* TODO(fork): enable the stitched cipher modes. */
-#if 0
-		if (s->ssl_version>>8 != TLS1_VERSION_MAJOR ||
-		    s->ssl_version < TLS1_VERSION)
-			return 1;
-
-		if	(c->algorithm_enc == SSL_RC4 &&
-			 c->algorithm_mac == SSL_MD5 &&
-			 (evp=EVP_get_cipherbyname("RC4-HMAC-MD5")))
-			*enc = evp, *md = NULL;
-		else if (c->algorithm_enc == SSL_AES128 &&
-			 c->algorithm_mac == SSL_SHA1 &&
-			 (evp=EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA1")))
-			*enc = evp, *md = NULL;
-		else if (c->algorithm_enc == SSL_AES256 &&
-			 c->algorithm_mac == SSL_SHA1 &&
-			 (evp=EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1")))
-			*enc = evp, *md = NULL;
-#endif
-
-  return 1;
-}
-
-int ssl_cipher_get_mac(const SSL_SESSION *s, const EVP_MD **md,
-                       int *mac_pkey_type, size_t *mac_secret_size) {
-  const SSL_CIPHER *c;
-
-  c = s->cipher;
-  if (c == NULL) {
-    return 0;
-  }
-
-  switch (c->algorithm_mac) {
-    case SSL_MD5:
-      *md = EVP_md5();
-      break;
-
-    case SSL_SHA1:
-      *md = EVP_sha1();
-      break;
-
-    case SSL_SHA256:
-      *md = EVP_sha256();
-      break;
-
-    case SSL_SHA384:
-      *md = EVP_sha384();
-      break;
-
-    default:
-      return 0;
-  }
-
-  if (mac_pkey_type != NULL) {
-    *mac_pkey_type = EVP_PKEY_HMAC;
-  }
-  if (mac_secret_size != NULL) {
-    *mac_secret_size = EVP_MD_size(*md);
-  }
-
-  return 1;
-}
-
 int ssl_get_handshake_digest(size_t idx, long *mask, const EVP_MD **md) {
   if (idx >= SSL_MAX_DIGEST) {
     return 0;
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 9e5af76..d179dc8 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -208,8 +208,6 @@
   s->packet_length = 0;
 
   ssl_clear_cipher_ctx(s);
-  ssl_clear_hash_ctx(&s->read_hash);
-  ssl_clear_hash_ctx(&s->write_hash);
 
   if (s->next_proto_negotiated) {
     OPENSSL_free(s->next_proto_negotiated);
@@ -607,8 +605,6 @@
   }
 
   ssl_clear_cipher_ctx(s);
-  ssl_clear_hash_ctx(&s->read_hash);
-  ssl_clear_hash_ctx(&s->write_hash);
 
   if (s->cert != NULL) {
     ssl_cert_free(s->cert);
@@ -2365,8 +2361,6 @@
   s->handshake_func = s->method->ssl_accept;
   /* clear the current cipher */
   ssl_clear_cipher_ctx(s);
-  ssl_clear_hash_ctx(&s->read_hash);
-  ssl_clear_hash_ctx(&s->write_hash);
 }
 
 void SSL_set_connect_state(SSL *s) {
@@ -2376,8 +2370,6 @@
   s->handshake_func = s->method->ssl_connect;
   /* clear the current cipher */
   ssl_clear_cipher_ctx(s);
-  ssl_clear_hash_ctx(&s->read_hash);
-  ssl_clear_hash_ctx(&s->write_hash);
 }
 
 int ssl_undefined_function(SSL *s) {
@@ -2426,18 +2418,6 @@
 }
 
 void ssl_clear_cipher_ctx(SSL *s) {
-  if (s->enc_read_ctx != NULL) {
-    EVP_CIPHER_CTX_cleanup(s->enc_read_ctx);
-    OPENSSL_free(s->enc_read_ctx);
-    s->enc_read_ctx = NULL;
-  }
-
-  if (s->enc_write_ctx != NULL) {
-    EVP_CIPHER_CTX_cleanup(s->enc_write_ctx);
-    OPENSSL_free(s->enc_write_ctx);
-    s->enc_write_ctx = NULL;
-  }
-
   if (s->aead_read_ctx != NULL) {
     EVP_AEAD_CTX_cleanup(&s->aead_read_ctx->ctx);
     OPENSSL_free(s->aead_read_ctx);
@@ -3186,27 +3166,6 @@
   return version;
 }
 
-/* Allocates new EVP_MD_CTX and sets pointer to it into given pointer vairable,
- * freeing  EVP_MD_CTX previously stored in that variable, if any. If EVP_MD
- * pointer is passed, initializes ctx with this md Returns newly allocated
- * ctx. */
-EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md) {
-  ssl_clear_hash_ctx(hash);
-  *hash = EVP_MD_CTX_create();
-  if (md != NULL && *hash != NULL && !EVP_DigestInit_ex(*hash, md, NULL)) {
-    EVP_MD_CTX_destroy(*hash);
-    *hash = NULL;
-  }
-  return *hash;
-}
-
-void ssl_clear_hash_ctx(EVP_MD_CTX **hash) {
-  if (*hash) {
-    EVP_MD_CTX_destroy(*hash);
-  }
-  *hash = NULL;
-}
-
 int SSL_cache_hit(SSL *s) { return s->hit; }
 
 int SSL_is_server(SSL *s) { return s->server; }
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index dd51e9e..b8e77e2 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -577,7 +577,6 @@
  * of a mess of functions, but hell, think of it as an opaque structure. */
 struct ssl3_enc_method {
   int (*enc)(SSL *, int);
-  int (*mac)(SSL *, uint8_t *, int);
   int (*prf)(SSL *, uint8_t *, size_t, const uint8_t *, size_t, const char *,
              size_t, const uint8_t *, size_t, const uint8_t *, size_t);
   int (*setup_key_block)(SSL *);
@@ -694,11 +693,6 @@
                             size_t *out_fixed_iv_len,
                             const SSL_CIPHER *cipher, uint16_t version);
 
-int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
-                       const EVP_MD **md, int *mac_pkey_type,
-                       size_t *mac_secret_size);
-int ssl_cipher_get_mac(const SSL_SESSION *s, const EVP_MD **md,
-                       int *mac_pkey_type, size_t *mac_secret_size);
 int ssl_get_handshake_digest(size_t i, long *mask, const EVP_MD **md);
 int ssl_cipher_get_cert_index(const SSL_CIPHER *c);
 int ssl_cipher_has_server_public_key(const SSL_CIPHER *cipher);
@@ -913,7 +907,6 @@
 int tls1_handshake_digest(SSL *s, uint8_t *out, size_t out_len);
 int tls1_final_finish_mac(SSL *s, const char *str, int slen, uint8_t *p);
 int tls1_cert_verify_mac(SSL *s, int md_nid, uint8_t *p);
-int tls1_mac(SSL *ssl, uint8_t *md, int snd);
 int tls1_generate_master_secret(SSL *s, uint8_t *out, const uint8_t *premaster,
                                 size_t premaster_len);
 int tls1_export_keying_material(SSL *s, uint8_t *out, size_t olen,
@@ -1030,8 +1023,6 @@
  * the wire version except at API boundaries. */
 uint16_t ssl3_version_from_wire(SSL *s, uint16_t wire_version);
 
-EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md);
-void ssl_clear_hash_ctx(EVP_MD_CTX **hash);
 int ssl_add_serverhello_renegotiate_ext(SSL *s, uint8_t *p, int *len,
                                         int maxlen);
 int ssl_parse_serverhello_renegotiate_ext(SSL *s, CBS *cbs, int *out_alert);
@@ -1055,19 +1046,4 @@
 int ssl_add_serverhello_use_srtp_ext(SSL *s, uint8_t *p, int *len, int maxlen);
 int ssl_parse_serverhello_use_srtp_ext(SSL *s, CBS *cbs, int *out_alert);
 
-/* s3_cbc.c */
-void ssl3_cbc_copy_mac(uint8_t *out, const SSL3_RECORD *rec, unsigned md_size,
-                       unsigned orig_len);
-int ssl3_cbc_remove_padding(const SSL *s, SSL3_RECORD *rec, unsigned block_size,
-                            unsigned mac_size);
-int tls1_cbc_remove_padding(const SSL *s, SSL3_RECORD *rec, unsigned block_size,
-                            unsigned mac_size);
-char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx);
-int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, 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);
-
 #endif
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index e4e9907..10d940f 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -307,20 +307,6 @@
   return 1;
 }
 
-static void tls1_cleanup_enc_ctx(EVP_CIPHER_CTX **ctx) {
-  if (*ctx != NULL) {
-    EVP_CIPHER_CTX_free(*ctx);
-  }
-  *ctx = NULL;
-}
-
-static void tls1_cleanup_hash_ctx(EVP_MD_CTX **ctx) {
-  if (*ctx != NULL) {
-    EVP_MD_CTX_destroy(*ctx);
-  }
-  *ctx = NULL;
-}
-
 static int tls1_change_cipher_state_aead(SSL *s, char is_read,
                                          const uint8_t *key, unsigned key_len,
                                          const uint8_t *iv, unsigned iv_len,
@@ -332,14 +318,6 @@
    * simulates pre-AEAD cipher suites. */
   uint8_t merged_key[EVP_AEAD_MAX_KEY_LENGTH];
 
-  if (is_read) {
-    tls1_cleanup_enc_ctx(&s->enc_read_ctx);
-    tls1_cleanup_hash_ctx(&s->read_hash);
-  } else {
-    tls1_cleanup_enc_ctx(&s->enc_write_ctx);
-    tls1_cleanup_hash_ctx(&s->write_hash);
-  }
-
   if (mac_secret_len > 0) {
     /* This is a "stateful" AEAD (for compatibility with pre-AEAD cipher
      * suites). */
@@ -422,120 +400,6 @@
   return 1;
 }
 
-static void tls1_cleanup_aead_ctx(SSL_AEAD_CTX **ctx) {
-  if (*ctx != NULL) {
-    EVP_AEAD_CTX_cleanup(&(*ctx)->ctx);
-    OPENSSL_free(*ctx);
-  }
-  *ctx = NULL;
-}
-
-/* tls1_change_cipher_state_cipher performs the work needed to switch cipher
- * states when using EVP_CIPHER. The argument |is_read| is true iff this
- * function is being called due to reading, as opposed to writing, a
- * ChangeCipherSpec message. In order to support export ciphersuites,
- * use_client_keys indicates whether the key material provided is in the
- * "client write" direction. */
-static int tls1_change_cipher_state_cipher(SSL *s, char is_read,
-                                           char use_client_keys,
-                                           const uint8_t *mac_secret,
-                                           unsigned mac_secret_len,
-                                           const uint8_t *key, unsigned key_len,
-                                           const uint8_t *iv, unsigned iv_len) {
-  const EVP_CIPHER *cipher = s->s3->tmp.new_sym_enc;
-  EVP_CIPHER_CTX *cipher_ctx;
-  EVP_MD_CTX *mac_ctx;
-
-  if (is_read) {
-    tls1_cleanup_aead_ctx(&s->aead_read_ctx);
-  } else {
-    /* When updating the cipher state for DTLS, we do not wish to free the old
-     * ones because DTLS stores pointers to them in order to implement
-     * retransmission. See dtls1_hm_fragment_free.
-     *
-     * TODO(davidben): Simplify aead_write_ctx ownership, probably by just
-     * forbidding DTLS renego. */
-    if (!SSL_IS_DTLS(s)) {
-      tls1_cleanup_aead_ctx(&s->aead_write_ctx);
-    } else {
-      s->aead_write_ctx = NULL;
-    }
-  }
-
-  if (is_read) {
-    if (s->enc_read_ctx != NULL && !SSL_IS_DTLS(s)) {
-      EVP_CIPHER_CTX_cleanup(s->enc_read_ctx);
-    } else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) {
-      goto err;
-    }
-
-    cipher_ctx = s->enc_read_ctx;
-    mac_ctx = ssl_replace_hash(&s->read_hash, NULL);
-    if (mac_ctx == NULL) {
-      goto err;
-    }
-
-    memcpy(s->s3->read_mac_secret, mac_secret, mac_secret_len);
-    s->s3->read_mac_secret_size = mac_secret_len;
-  } else {
-    /* When updating the write contexts for DTLS, we do not wish to free the
-     * old ones because DTLS stores pointers to them in order to implement
-     * retransmission. */
-
-    if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s)) {
-      EVP_CIPHER_CTX_cleanup(s->enc_write_ctx);
-    } else {
-      s->enc_write_ctx = OPENSSL_malloc(sizeof(EVP_CIPHER_CTX));
-      if (s->enc_write_ctx == NULL) {
-        goto err;
-      }
-    }
-    EVP_CIPHER_CTX_init(s->enc_write_ctx);
-
-    cipher_ctx = s->enc_write_ctx;
-    if (SSL_IS_DTLS(s)) {
-      /* This is the same as ssl_replace_hash, but doesn't
-       * free the old |s->write_hash|. */
-      mac_ctx = EVP_MD_CTX_create();
-      if (!mac_ctx) {
-        goto err;
-      }
-      s->write_hash = mac_ctx;
-    } else {
-      mac_ctx = ssl_replace_hash(&s->write_hash, NULL);
-      if (mac_ctx == NULL) {
-        goto err;
-      }
-    }
-
-    memcpy(s->s3->write_mac_secret, mac_secret, mac_secret_len);
-    s->s3->write_mac_secret_size = mac_secret_len;
-  }
-
-  EVP_PKEY *mac_key = EVP_PKEY_new_mac_key(s->s3->tmp.new_mac_pkey_type, NULL,
-                                           mac_secret, mac_secret_len);
-  if (!mac_key) {
-    return 0;
-  }
-
-  if (!EVP_DigestSignInit(mac_ctx, NULL, s->s3->tmp.new_hash, NULL, mac_key)) {
-    EVP_PKEY_free(mac_key);
-    goto err;
-  }
-  EVP_PKEY_free(mac_key);
-
-  if (!EVP_CipherInit_ex(cipher_ctx, cipher, NULL /* engine */, key, iv,
-                         !is_read)) {
-    goto err;
-  }
-
-  return 1;
-
-err:
-  OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state_cipher, ERR_R_MALLOC_FAILURE);
-  return 0;
-}
-
 int tls1_change_cipher_state(SSL *s, int which) {
   /* is_read is true if we have just read a ChangeCipherSpec message - i.e. we
    * need to update the read cipherspec. Otherwise we have just written one. */
@@ -548,7 +412,6 @@
   const uint8_t *client_write_mac_secret, *server_write_mac_secret, *mac_secret;
   const uint8_t *client_write_key, *server_write_key, *key;
   const uint8_t *client_write_iv, *server_write_iv, *iv;
-  const EVP_CIPHER *cipher = s->s3->tmp.new_sym_enc;
   const EVP_AEAD *aead = s->s3->tmp.new_aead;
   size_t key_len, iv_len, mac_secret_len;
   const uint8_t *key_data;
@@ -561,20 +424,21 @@
   mac_secret_len = s->s3->tmp.new_mac_secret_len;
   iv_len = s->s3->tmp.new_fixed_iv_len;
 
-  if (aead != NULL) {
-    key_len = EVP_AEAD_key_length(aead);
-    if (mac_secret_len > 0) {
-      /* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites)
-       * the key length reported by |EVP_AEAD_key_length| will include the MAC
-       * and IV key bytes. */
-      if (key_len < mac_secret_len + iv_len) {
-        OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state, ERR_R_INTERNAL_ERROR);
-        return 0;
-      }
-      key_len -= mac_secret_len + iv_len;
+  if (aead == NULL) {
+    OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state, ERR_R_INTERNAL_ERROR);
+    return 0;
+  }
+
+  key_len = EVP_AEAD_key_length(aead);
+  if (mac_secret_len > 0) {
+    /* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher
+     * suites) the key length reported by |EVP_AEAD_key_length| will
+     * include the MAC and IV key bytes. */
+    if (key_len < mac_secret_len + iv_len) {
+      OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state, ERR_R_INTERNAL_ERROR);
+      return 0;
     }
-  } else {
-    key_len = EVP_CIPHER_key_length(cipher);
+    key_len -= mac_secret_len + iv_len;
   }
 
   key_data = s->s3->tmp.key_block;
@@ -606,33 +470,17 @@
     return 0;
   }
 
-  if (aead != NULL) {
-    if (!tls1_change_cipher_state_aead(s, is_read, key, key_len, iv, iv_len,
-                                       mac_secret, mac_secret_len)) {
-      return 0;
-    }
-  } else {
-    if (!tls1_change_cipher_state_cipher(s, is_read, use_client_keys,
-                                         mac_secret, mac_secret_len, key,
-                                         key_len, iv, iv_len)) {
-      return 0;
-    }
-  }
-
-  return 1;
+  return tls1_change_cipher_state_aead(s, is_read, key, key_len, iv, iv_len,
+                                       mac_secret, mac_secret_len);
 }
 
 int tls1_setup_key_block(SSL *s) {
   uint8_t *p;
-  const EVP_CIPHER *c = NULL;
-  const EVP_MD *hash = NULL;
   const EVP_AEAD *aead = NULL;
-  int mac_type = NID_undef;
   int ret = 0;
   size_t mac_secret_len, fixed_iv_len, variable_iv_len, key_len;
   size_t key_block_len;
 
-
   if (s->s3->tmp.key_block_length != 0) {
     return 1;
   }
@@ -641,40 +489,29 @@
     goto cipher_unavailable_err;
   }
 
-  /* TODO(davidben): Prune away dead code. To be done in follow-up commit. */
-  if (1) {
-    if (!ssl_cipher_get_evp_aead(&aead, &mac_secret_len, &fixed_iv_len,
-                                 s->session->cipher,
-                                 ssl3_version_from_wire(s, s->version))) {
-      goto cipher_unavailable_err;
+  if (!ssl_cipher_get_evp_aead(&aead, &mac_secret_len, &fixed_iv_len,
+                               s->session->cipher,
+                               ssl3_version_from_wire(s, s->version))) {
+    goto cipher_unavailable_err;
+  }
+  key_len = EVP_AEAD_key_length(aead);
+  variable_iv_len = EVP_AEAD_nonce_length(aead);
+  if (mac_secret_len > 0) {
+    /* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites) the
+     * key length reported by |EVP_AEAD_key_length| will include the MAC key
+     * bytes and initial implicit IV. */
+    if (key_len < mac_secret_len + fixed_iv_len) {
+      OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_INTERNAL_ERROR);
+      return 0;
     }
-    key_len = EVP_AEAD_key_length(aead);
-    variable_iv_len = EVP_AEAD_nonce_length(aead);
-    if (mac_secret_len > 0) {
-      /* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites)
-       * the key length reported by |EVP_AEAD_key_length| will include the MAC
-       * key bytes and initial implicit IV. */
-      if (key_len < mac_secret_len + fixed_iv_len) {
-        OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_INTERNAL_ERROR);
-        return 0;
-      }
-      key_len -= mac_secret_len + fixed_iv_len;
-    } else {
-      /* The nonce is split into a fixed portion and a variable portion. */
-      if (variable_iv_len < fixed_iv_len) {
-        OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_INTERNAL_ERROR);
-        return 0;
-      }
-      variable_iv_len -= fixed_iv_len;
-    }
+    key_len -= mac_secret_len + fixed_iv_len;
   } else {
-    if (!ssl_cipher_get_evp(s->session, &c, &hash, &mac_type,
-                            &mac_secret_len)) {
-      goto cipher_unavailable_err;
+    /* The nonce is split into a fixed portion and a variable portion. */
+    if (variable_iv_len < fixed_iv_len) {
+      OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_INTERNAL_ERROR);
+      return 0;
     }
-    key_len = EVP_CIPHER_key_length(c);
-    fixed_iv_len = EVP_CIPHER_iv_length(c);
-    variable_iv_len = 0;
+    variable_iv_len -= fixed_iv_len;
   }
 
   assert(mac_secret_len < 256);
@@ -682,9 +519,6 @@
   assert(variable_iv_len < 256);
 
   s->s3->tmp.new_aead = aead;
-  s->s3->tmp.new_sym_enc = c;
-  s->s3->tmp.new_hash = hash;
-  s->s3->tmp.new_mac_pkey_type = mac_type;
   s->s3->tmp.new_mac_secret_len = (uint8_t)mac_secret_len;
   s->s3->tmp.new_fixed_iv_len = (uint8_t)fixed_iv_len;
   s->s3->tmp.new_variable_iv_len = (uint8_t)variable_iv_len;
@@ -741,10 +575,6 @@
  *       an internal error occured. */
 int tls1_enc(SSL *s, int send) {
   SSL3_RECORD *rec;
-  EVP_CIPHER_CTX *ds;
-  unsigned long l;
-  int bs, i, j, k, pad = 0, ret, mac_size = 0;
-  const EVP_CIPHER *enc;
   const SSL_AEAD_CTX *aead;
 
   if (send) {
@@ -755,215 +585,140 @@
     aead = s->aead_read_ctx;
   }
 
-  if (aead) {
-    uint8_t ad[13], *seq, *in, *out, nonce[EVP_AEAD_MAX_NONCE_LENGTH];
-    unsigned nonce_used;
-    size_t n, ad_len;
-
-    seq = send ? s->s3->write_sequence : s->s3->read_sequence;
-
-    if (SSL_IS_DTLS(s)) {
-      uint8_t dtlsseq[9], *p = dtlsseq;
-
-      s2n(send ? s->d1->w_epoch : s->d1->r_epoch, p);
-      memcpy(p, &seq[2], 6);
-      memcpy(ad, dtlsseq, 8);
-    } else {
-      memcpy(ad, seq, 8);
-      for (i = 7; i >= 0; i--) {
-        ++seq[i];
-        if (seq[i] != 0) {
-          break;
-        }
-      }
-    }
-
-    ad[8] = rec->type;
-    ad_len = 9;
-    if (!aead->omit_version_in_ad) {
-      ad[ad_len++] = (uint8_t)(s->version >> 8);
-      ad[ad_len++] = (uint8_t)(s->version);
-    }
-
-    if (aead->fixed_nonce_len + aead->variable_nonce_len > sizeof(nonce)) {
-      OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR);
-      return -1; /* internal error - should never happen. */
-    }
-
-    memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len);
-    nonce_used = aead->fixed_nonce_len;
-
-    if (send) {
-      size_t len = rec->length;
-      size_t eivlen = 0;
-      in = rec->input;
-      out = rec->data;
-
-      uint8_t *variable_nonce = nonce + nonce_used;
-      if (aead->random_variable_nonce) {
-        assert(aead->variable_nonce_included_in_record);
-        if (!RAND_bytes(nonce + nonce_used, aead->variable_nonce_len)) {
-          return -1;
-        }
-      } else {
-        /* When sending we use the sequence number as the variable part of the
-         * nonce. */
-        if (aead->variable_nonce_len != 8) {
-          OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR);
-          return -1;
-        }
-        memcpy(nonce + nonce_used, ad, aead->variable_nonce_len);
-      }
-      nonce_used += aead->variable_nonce_len;
-
-      /* in do_ssl3_write, rec->input is moved forward by variable_nonce_len in
-       * order to leave space for the variable nonce. Thus we can copy the
-       * sequence number bytes into place without overwriting any of the
-       * plaintext. */
-      if (aead->variable_nonce_included_in_record) {
-        memcpy(out, variable_nonce, aead->variable_nonce_len);
-        len -= aead->variable_nonce_len;
-        eivlen = aead->variable_nonce_len;
-      }
-
-      if (!aead->omit_length_in_ad) {
-        ad[ad_len++] = len >> 8;
-        ad[ad_len++] = len & 0xff;
-      }
-
-      if (!EVP_AEAD_CTX_seal(&aead->ctx, out + eivlen, &n, len + aead->tag_len,
-                             nonce, nonce_used, in + eivlen, len, ad, ad_len)) {
-        return -1;
-      }
-
-      if (aead->variable_nonce_included_in_record) {
-        n += aead->variable_nonce_len;
-      }
-    } else {
-      /* receive */
-      size_t len = rec->length;
-
-      if (rec->data != rec->input) {
-        OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR);
-        return -1; /* internal error - should never happen. */
-      }
-      out = in = rec->input;
-
-      if (len < aead->variable_nonce_len) {
-        return 0;
-      }
-      memcpy(nonce + nonce_used,
-             aead->variable_nonce_included_in_record ? in : ad,
-             aead->variable_nonce_len);
-      nonce_used += aead->variable_nonce_len;
-
-      if (aead->variable_nonce_included_in_record) {
-        in += aead->variable_nonce_len;
-        len -= aead->variable_nonce_len;
-        out += aead->variable_nonce_len;
-      }
-
-      if (!aead->omit_length_in_ad) {
-        if (len < aead->tag_len) {
-          return 0;
-        }
-        size_t plaintext_len = len - aead->tag_len;
-
-        ad[ad_len++] = plaintext_len >> 8;
-        ad[ad_len++] = plaintext_len & 0xff;
-      }
-
-      if (!EVP_AEAD_CTX_open(&aead->ctx, out, &n, rec->length, nonce, nonce_used, in,
-                             len, ad, ad_len)) {
-        return -1;
-      }
-
-      rec->data = rec->input = out;
-    }
-
-    rec->length = n;
+  if (s->session == NULL || aead == NULL) {
+    memmove(rec->data, rec->input, rec->length);
+    rec->input = rec->data;
     return 1;
   }
 
-  if (send) {
-    ds = s->enc_write_ctx;
-    rec = &(s->s3->wrec);
-    if (s->enc_write_ctx == NULL) {
-      enc = NULL;
-    } else {
-      int ivlen;
-      enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
-      /* For TLSv1.1 and later explicit IV */
-      if (SSL_USE_EXPLICIT_IV(s) && EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE) {
-        ivlen = EVP_CIPHER_iv_length(enc);
-      } else {
-        ivlen = 0;
-      }
+  uint8_t ad[13], *seq, *in, *out, nonce[EVP_AEAD_MAX_NONCE_LENGTH];
+  unsigned nonce_used;
+  size_t n, ad_len;
 
-      if (ivlen > 1) {
-        if (rec->data != rec->input) {
-          /* we can't write into the input stream:
-           * Can this ever happen?? (steve)
-           */
-          fprintf(stderr, "%s:%d: rec->data != rec->input\n", __FILE__,
-                  __LINE__);
-        } else if (!RAND_bytes(rec->input, ivlen)) {
-          return -1;
-        }
-      }
-    }
+  seq = send ? s->s3->write_sequence : s->s3->read_sequence;
+
+  if (SSL_IS_DTLS(s)) {
+    uint8_t dtlsseq[9], *p = dtlsseq;
+
+    s2n(send ? s->d1->w_epoch : s->d1->r_epoch, p);
+    memcpy(p, &seq[2], 6);
+    memcpy(ad, dtlsseq, 8);
   } else {
-    ds = s->enc_read_ctx;
-    rec = &(s->s3->rrec);
-    if (s->enc_read_ctx == NULL) {
-      enc = NULL;
-    } else {
-      enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
+    int i;
+    memcpy(ad, seq, 8);
+    for (i = 7; i >= 0; i--) {
+      ++seq[i];
+      if (seq[i] != 0) {
+        break;
+      }
     }
   }
 
-  if (s->session == NULL || ds == NULL || enc == NULL) {
-    memmove(rec->data, rec->input, rec->length);
-    rec->input = rec->data;
-    ret = 1;
-  } else {
-    l = rec->length;
-    bs = EVP_CIPHER_block_size(ds->cipher);
+  ad[8] = rec->type;
+  ad_len = 9;
+  if (!aead->omit_version_in_ad) {
+    ad[ad_len++] = (uint8_t)(s->version >> 8);
+    ad[ad_len++] = (uint8_t)(s->version);
+  }
 
-    if (bs != 1 && send) {
-      i = bs - ((int)l % bs);
+  if (aead->fixed_nonce_len + aead->variable_nonce_len > sizeof(nonce)) {
+    OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR);
+    return -1; /* internal error - should never happen. */
+  }
 
-      /* Add weird padding of upto 256 bytes */
-      /* we need to add 'i' padding bytes of value j */
-      j = i - 1;
-      for (k = (int)l; k < (int)(l + i); k++) {
-        rec->input[k] = j;
+  memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len);
+  nonce_used = aead->fixed_nonce_len;
+
+  if (send) {
+    size_t len = rec->length;
+    size_t eivlen = 0;
+    in = rec->input;
+    out = rec->data;
+
+    uint8_t *variable_nonce = nonce + nonce_used;
+    if (aead->random_variable_nonce) {
+      assert(aead->variable_nonce_included_in_record);
+      if (!RAND_bytes(nonce + nonce_used, aead->variable_nonce_len)) {
+        return -1;
       }
-      l += i;
-      rec->length += i;
+    } else {
+      /* When sending we use the sequence number as the variable part of the
+       * nonce. */
+      if (aead->variable_nonce_len != 8) {
+        OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR);
+        return -1;
+      }
+      memcpy(nonce + nonce_used, ad, aead->variable_nonce_len);
+    }
+    nonce_used += aead->variable_nonce_len;
+
+    /* in do_ssl3_write, rec->input is moved forward by variable_nonce_len in
+     * order to leave space for the variable nonce. Thus we can copy the
+     * sequence number bytes into place without overwriting any of the
+     * plaintext. */
+    if (aead->variable_nonce_included_in_record) {
+      memcpy(out, variable_nonce, aead->variable_nonce_len);
+      len -= aead->variable_nonce_len;
+      eivlen = aead->variable_nonce_len;
     }
 
-    if (!send && (l == 0 || l % bs != 0)) {
-      return 0;
+    if (!aead->omit_length_in_ad) {
+      ad[ad_len++] = len >> 8;
+      ad[ad_len++] = len & 0xff;
     }
 
-    if (!EVP_Cipher(ds, rec->data, rec->input, l)) {
+    if (!EVP_AEAD_CTX_seal(&aead->ctx, out + eivlen, &n, len + aead->tag_len,
+                           nonce, nonce_used, in + eivlen, len, ad, ad_len)) {
       return -1;
     }
 
-    ret = 1;
-    if (EVP_MD_CTX_md(s->read_hash) != NULL) {
-      mac_size = EVP_MD_CTX_size(s->read_hash);
+    if (aead->variable_nonce_included_in_record) {
+      n += aead->variable_nonce_len;
+    }
+  } else {
+    /* receive */
+    size_t len = rec->length;
+
+    if (rec->data != rec->input) {
+      OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR);
+      return -1; /* internal error - should never happen. */
+    }
+    out = in = rec->input;
+
+    if (len < aead->variable_nonce_len) {
+      return 0;
+    }
+    memcpy(nonce + nonce_used,
+           aead->variable_nonce_included_in_record ? in : ad,
+           aead->variable_nonce_len);
+    nonce_used += aead->variable_nonce_len;
+
+    if (aead->variable_nonce_included_in_record) {
+      in += aead->variable_nonce_len;
+      len -= aead->variable_nonce_len;
+      out += aead->variable_nonce_len;
     }
 
-    if (bs != 1 && !send) {
-      ret = tls1_cbc_remove_padding(s, rec, bs, mac_size);
+    if (!aead->omit_length_in_ad) {
+      if (len < aead->tag_len) {
+        return 0;
+      }
+      size_t plaintext_len = len - aead->tag_len;
+
+      ad[ad_len++] = plaintext_len >> 8;
+      ad[ad_len++] = plaintext_len & 0xff;
     }
-    if (pad && !send) {
-      rec->length -= pad;
+
+    if (!EVP_AEAD_CTX_open(&aead->ctx, out, &n, rec->length, nonce, nonce_used, in,
+                           len, ad, ad_len)) {
+      return -1;
     }
+
+    rec->data = rec->input = out;
   }
-  return ret;
+
+  rec->length = n;
+  return 1;
 }
 
 int tls1_cert_verify_mac(SSL *s, int md_nid, uint8_t *out) {
@@ -1072,89 +827,6 @@
   }
 }
 
-int tls1_mac(SSL *ssl, uint8_t *md, int send) {
-  SSL3_RECORD *rec;
-  uint8_t *seq;
-  EVP_MD_CTX *hash;
-  size_t md_size, orig_len;
-  int i, ok;
-  EVP_MD_CTX hmac, *mac_ctx;
-  uint8_t header[13];
-  int t;
-
-  if (send) {
-    rec = &ssl->s3->wrec;
-    seq = &ssl->s3->write_sequence[0];
-    hash = ssl->write_hash;
-  } else {
-    rec = &ssl->s3->rrec;
-    seq = &ssl->s3->read_sequence[0];
-    hash = ssl->read_hash;
-  }
-
-  t = EVP_MD_CTX_size(hash);
-  assert(t >= 0);
-  md_size = t;
-
-  mac_ctx = &hmac;
-  if (!EVP_MD_CTX_copy(mac_ctx, hash)) {
-    return -1;
-  }
-
-  if (SSL_IS_DTLS(ssl)) {
-    uint8_t dtlsseq[8], *p = dtlsseq;
-
-    s2n(send ? ssl->d1->w_epoch : ssl->d1->r_epoch, p);
-    memcpy(p, &seq[2], 6);
-
-    memcpy(header, dtlsseq, 8);
-  } else {
-    memcpy(header, seq, 8);
-  }
-
-  /* kludge: tls1_cbc_remove_padding passes padding length in rec->type */
-  orig_len = rec->length + md_size + ((unsigned int)rec->type >> 8);
-  rec->type &= 0xff;
-
-  header[8] = rec->type;
-  header[9] = (uint8_t)(ssl->version >> 8);
-  header[10] = (uint8_t)(ssl->version);
-  header[11] = (rec->length) >> 8;
-  header[12] = (rec->length) & 0xff;
-
-  if (!send && EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
-      ssl3_cbc_record_digest_supported(mac_ctx)) {
-    /* This is a CBC-encrypted record. We must avoid leaking any timing-side
-     * channel information about how many blocks of data we are hashing because
-     * that gives an attacker a timing-oracle. */
-    ok = ssl3_cbc_digest_record(
-        mac_ctx, md, &md_size, header, rec->input, rec->length + md_size,
-        orig_len, ssl->s3->read_mac_secret, ssl->s3->read_mac_secret_size,
-        0 /* not SSLv3 */);
-  } else {
-    EVP_DigestSignUpdate(mac_ctx, header, sizeof(header));
-    EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length);
-    ok = EVP_DigestSignFinal(mac_ctx, md, &md_size);
-  }
-
-  EVP_MD_CTX_cleanup(mac_ctx);
-
-  if (!ok) {
-    return -1;
-  }
-
-  if (!SSL_IS_DTLS(ssl)) {
-    for (i = 7; i >= 0; i--) {
-      ++seq[i];
-      if (seq[i] != 0) {
-        break;
-      }
-    }
-  }
-
-  return md_size;
-}
-
 int tls1_generate_master_secret(SSL *s, uint8_t *out, const uint8_t *premaster,
                                 size_t premaster_len) {
   if (s->s3->tmp.extended_master_secret) {
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 9b212a5..a420989 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -128,7 +128,6 @@
 
 const SSL3_ENC_METHOD TLSv1_enc_data = {
     tls1_enc,
-    tls1_mac,
     tls1_prf,
     tls1_setup_key_block,
     tls1_generate_master_secret,
@@ -148,7 +147,6 @@
 
 const SSL3_ENC_METHOD TLSv1_1_enc_data = {
     tls1_enc,
-    tls1_mac,
     tls1_prf,
     tls1_setup_key_block,
     tls1_generate_master_secret,
@@ -168,7 +166,6 @@
 
 const SSL3_ENC_METHOD TLSv1_2_enc_data = {
     tls1_enc,
-    tls1_mac,
     tls1_prf,
     tls1_setup_key_block,
     tls1_generate_master_secret,