Pull SSL3_ENC_METHOD out of SSL_METHOD.

SSL3_ENC_METHOD will remain version-specific while SSL_METHOD will become
protocol-specific. This finally removes all the version-specific portions of
SSL_METHOD but the version tag itself.

(SSL3_ENC_METHOD's version-specific bits themselves can probably be handled by
tracking a canonicalized protocol version. It would simplify version
comparisons anyway. The one catch is SSLv3 has a very different table. But
that's a cleanup for future. Then again, perhaps a version-specific method
table swap somewhere will be useful later for TLS 1.3.)

Much of this commit was generated with sed invocation:
    s/method->ssl3_enc/enc_method/g

Change-Id: I2b192507876aadd4f9310240687e562e56e6c0b1
Reviewed-on: https://boringssl-review.googlesource.com/2581
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index e40f739..b4cda2b 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -345,7 +345,6 @@
 	int (*ssl_pending)(const SSL *s);
 	int (*num_ciphers)(void);
 	const SSL_CIPHER *(*get_cipher)(unsigned ncipher);
-	const SSL3_ENC_METHOD *ssl3_enc; /* Extra SSLv3/TLS stuff */
 	int (*ssl_version)(void);
 	long (*ssl_callback_ctrl)(SSL *s, int cb_id, void (*fp)(void));
 	long (*ssl_ctx_callback_ctrl)(SSL_CTX *s, int cb_id, void (*fp)(void));
@@ -1168,7 +1167,16 @@
 	/* version is the protocol version. */
 	int version;
 
-	const SSL_METHOD *method; /* SSLv3 */
+	/* method is the method table corresponding to the current protocol
+	 * (DTLS or TLS).
+	 *
+	 * TODO(davidben): For now, it also corresponds to the protocol version,
+	 * but that will soon change. */
+	const SSL_METHOD *method;
+
+	/* enc_method is the method table corresponding to the current protocol
+	 * version. */
+	const SSL3_ENC_METHOD *enc_method;
 
 	/* There are 2 BIO's even though they are normally both the
 	 * same.  This is so data can be read and written to different
diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c
index c787167..55b6aca 100644
--- a/ssl/d1_clnt.c
+++ b/ssl/d1_clnt.c
@@ -376,13 +376,13 @@
 			s->init_num=0;
 
 			s->session->cipher=s->s3->tmp.new_cipher;
-			if (!s->method->ssl3_enc->setup_key_block(s))
+			if (!s->enc_method->setup_key_block(s))
 				{
 				ret= -1;
 				goto end;
 				}
 
-			if (!s->method->ssl3_enc->change_cipher_state(s,
+			if (!s->enc_method->change_cipher_state(s,
 				SSL3_CHANGE_CIPHER_CLIENT_WRITE))
 				{
 				ret= -1;
@@ -398,8 +398,8 @@
 				dtls1_start_timer(s);
 			ret=ssl3_send_finished(s,
 				SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B,
-				s->method->ssl3_enc->client_finished_label,
-				s->method->ssl3_enc->client_finished_label_len);
+				s->enc_method->client_finished_label,
+				s->enc_method->client_finished_label_len);
 			if (ret <= 0) goto end;
 			s->state=SSL3_ST_CW_FLUSH;
 
diff --git a/ssl/d1_meth.c b/ssl/d1_meth.c
index b2b9a75..5e30251 100644
--- a/ssl/d1_meth.c
+++ b/ssl/d1_meth.c
@@ -58,11 +58,11 @@
 #include "ssl_locl.h"
 
 
-IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, DTLSv1_method, DTLSv1_enc_data)
+IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, DTLSv1_method)
 
-IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, DTLSv1_2_method, DTLSv1_2_enc_data)
+IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, DTLSv1_2_method)
 
-IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, DTLS_method, DTLSv1_2_enc_data)
+IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, DTLS_method)
 
 const SSL_METHOD *DTLSv1_2_server_method(void)
 	{
diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c
index 1b3bd0b..4f98ac9 100644
--- a/ssl/d1_pkt.c
+++ b/ssl/d1_pkt.c
@@ -404,7 +404,7 @@
 	/* decrypt in place in 'rr->input' */
 	rr->data=rr->input;
 
-	enc_err = s->method->ssl3_enc->enc(s,0);
+	enc_err = s->enc_method->enc(s,0);
 	/* enc_err is:
 	 *    0: (in non-constant time) if the record is publically invalid.
 	 *    1: if the padding is valid
@@ -472,7 +472,7 @@
 			mac = &rr->data[rr->length];
 			}
 
-		i=s->method->ssl3_enc->mac(s,md,0 /* not send */);
+		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)
@@ -1368,7 +1368,7 @@
 
 	if (mac_size != 0)
 		{
-		if(s->method->ssl3_enc->mac(s,&(p[wr->length + eivlen]),1) < 0)
+		if(s->enc_method->mac(s,&(p[wr->length + eivlen]),1) < 0)
 			goto err;
 		wr->length+=mac_size;
 		}
@@ -1380,7 +1380,7 @@
 	if (eivlen)
 		wr->length += eivlen;
 
-	if (s->method->ssl3_enc->enc(s, 1) < 1)
+	if (s->enc_method->enc(s, 1) < 1)
 		goto err;
 
 	/* record length after mac and block padding */
diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c
index 3320f75..fad8958 100644
--- a/ssl/d1_srvr.c
+++ b/ssl/d1_srvr.c
@@ -488,7 +488,7 @@
 		case SSL3_ST_SW_CHANGE_B:
 
 			s->session->cipher=s->s3->tmp.new_cipher;
-			if (!s->method->ssl3_enc->setup_key_block(s))
+			if (!s->enc_method->setup_key_block(s))
 				{ ret= -1; goto end; }
 
 			ret=dtls1_send_change_cipher_spec(s,
@@ -499,7 +499,7 @@
 			s->state=SSL3_ST_SW_FINISHED_A;
 			s->init_num=0;
 
-			if (!s->method->ssl3_enc->change_cipher_state(s,
+			if (!s->enc_method->change_cipher_state(s,
 				SSL3_CHANGE_CIPHER_SERVER_WRITE))
 				{
 				ret= -1;
@@ -513,8 +513,8 @@
 		case SSL3_ST_SW_FINISHED_B:
 			ret=ssl3_send_finished(s,
 				SSL3_ST_SW_FINISHED_A,SSL3_ST_SW_FINISHED_B,
-				s->method->ssl3_enc->server_finished_label,
-				s->method->ssl3_enc->server_finished_label_len);
+				s->enc_method->server_finished_label,
+				s->enc_method->server_finished_label_len);
 			if (ret <= 0) goto end;
 			s->state=SSL3_ST_SW_FLUSH;
 			if (s->hit)
diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c
index ca46d8d..8ff3087 100644
--- a/ssl/s23_clnt.c
+++ b/ssl/s23_clnt.c
@@ -1,5 +1,5 @@
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+* All rights reserved.
  *
  * This package is an SSL implementation written
  * by Eric Young (eay@cryptsoft.com).
@@ -456,6 +456,8 @@
 		s->version = version;
 		s->method = ssl3_get_method(version);
 		assert(s->method != NULL);
+		s->enc_method = ssl3_get_enc_method(s->version);
+		assert(s->enc_method != NULL);
 
 		if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING)
 			{
diff --git a/ssl/s23_srvr.c b/ssl/s23_srvr.c
index 08d063a..55ffee5 100644
--- a/ssl/s23_srvr.c
+++ b/ssl/s23_srvr.c
@@ -201,6 +201,8 @@
 			s->state = SSL3_ST_SR_CLNT_HELLO_A;
 			s->method = ssl3_get_method(s->version);
 			assert(s->method != NULL);
+			s->enc_method = ssl3_get_enc_method(s->version);
+			assert(s->enc_method != NULL);
 			s->handshake_func = s->method->ssl_accept;
 			s->init_num = 0;
 
diff --git a/ssl/s3_both.c b/ssl/s3_both.c
index bdbb666..7495ea6 100644
--- a/ssl/s3_both.c
+++ b/ssl/s3_both.c
@@ -162,7 +162,7 @@
 		{
 		p = ssl_handshake_start(s);
 
-		i=s->method->ssl3_enc->final_finish_mac(s,
+		i=s->enc_method->final_finish_mac(s,
 			sender,slen,s->s3->tmp.finish_md);
 		if (i == 0)
 			return 0;
@@ -215,16 +215,16 @@
 		return;
 	if (s->state & SSL_ST_CONNECT)
 		{
-		sender=s->method->ssl3_enc->server_finished_label;
-		slen=s->method->ssl3_enc->server_finished_label_len;
+		sender=s->enc_method->server_finished_label;
+		slen=s->enc_method->server_finished_label_len;
 		}
 	else
 		{
-		sender=s->method->ssl3_enc->client_finished_label;
-		slen=s->method->ssl3_enc->client_finished_label_len;
+		sender=s->enc_method->client_finished_label;
+		slen=s->enc_method->client_finished_label_len;
 		}
 
-	s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
+	s->s3->tmp.peer_finish_md_len = s->enc_method->final_finish_mac(s,
 		sender,slen,s->s3->tmp.peer_finish_md);
 	}
 
@@ -519,8 +519,8 @@
 		}
 	else if (pkey->type == EVP_PKEY_RSA)
 		{
-		if (s->method->ssl3_enc->cert_verify_mac(s, NID_md5, out) == 0 ||
-			s->method->ssl3_enc->cert_verify_mac(s,
+		if (s->enc_method->cert_verify_mac(s, NID_md5, out) == 0 ||
+			s->enc_method->cert_verify_mac(s,
 				NID_sha1, out + MD5_DIGEST_LENGTH) == 0)
 			return 0;
 		*out_len = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH;
@@ -528,7 +528,7 @@
 		}
 	else if (pkey->type == EVP_PKEY_EC)
 		{
-		if (s->method->ssl3_enc->cert_verify_mac(s, NID_sha1, out) == 0)
+		if (s->enc_method->cert_verify_mac(s, NID_sha1, out) == 0)
 			return 0;
 		*out_len = SHA_DIGEST_LENGTH;
 		*out_md = EVP_sha1();
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index c7ae0ee..5570a82 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -381,13 +381,13 @@
 			s->init_num=0;
 
 			s->session->cipher=s->s3->tmp.new_cipher;
-			if (!s->method->ssl3_enc->setup_key_block(s))
+			if (!s->enc_method->setup_key_block(s))
 				{
 				ret= -1;
 				goto end;
 				}
 
-			if (!s->method->ssl3_enc->change_cipher_state(s,
+			if (!s->enc_method->change_cipher_state(s,
 				SSL3_CHANGE_CIPHER_CLIENT_WRITE))
 				{
 				ret= -1;
@@ -417,8 +417,8 @@
 		case SSL3_ST_CW_FINISHED_B:
 			ret=ssl3_send_finished(s,
 				SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B,
-				s->method->ssl3_enc->client_finished_label,
-				s->method->ssl3_enc->client_finished_label_len);
+				s->enc_method->client_finished_label,
+				s->enc_method->client_finished_label_len);
 			if (ret <= 0) goto end;
 			s->state=SSL3_ST_CW_FLUSH;
 
@@ -783,6 +783,8 @@
 		s->version = server_version;
 		s->method = ssl3_get_method(server_version);
 		assert(s->method != NULL);
+		s->enc_method = ssl3_get_enc_method(server_version);
+		assert(s->enc_method != NULL);
 		}
 
 	if (server_version != s->version)
@@ -2091,10 +2093,10 @@
 
 		/* The message must be added to the finished hash before
 		 * calculating the master secret. */
-		s->method->ssl3_enc->add_to_finished_hash(s);
+		s->enc_method->add_to_finished_hash(s);
 
 		s->session->master_key_length =
-			s->method->ssl3_enc->generate_master_secret(s,
+			s->enc_method->generate_master_secret(s,
 				s->session->master_key,
 				pms, pms_len);
 		if (s->session->master_key_length == 0)
@@ -2108,7 +2110,7 @@
 
 	/* SSL3_ST_CW_KEY_EXCH_B */
 	/* The message has already been added to the finished hash. */
-	return s->method->ssl3_enc->do_write(s, dont_add_to_finished_hash);
+	return s->enc_method->do_write(s, dont_add_to_finished_hash);
 
 err:
 	BN_CTX_free(bn_ctx);
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index d41294a..8176b2a 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -2056,7 +2056,7 @@
 	{
 	static const unsigned long kMask = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF;
 	long alg2 = s->s3->tmp.new_cipher->algorithm2;
-	if (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF
+	if (s->enc_method->enc_flags & SSL_ENC_FLAG_SHA256_PRF
 	    && (alg2 & kMask) == kMask)
 		return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
 	return alg2;
diff --git a/ssl/s3_meth.c b/ssl/s3_meth.c
index 3bdb7a7..2bf4dd2 100644
--- a/ssl/s3_meth.c
+++ b/ssl/s3_meth.c
@@ -58,13 +58,13 @@
 #include "ssl_locl.h"
 
 
-IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_method, TLSv1_2_enc_data)
+IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_method)
 
-IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_method, TLSv1_1_enc_data)
+IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_method)
 
-IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_method, TLSv1_enc_data)
+IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_method)
 
-IMPLEMENT_tls_meth_func(SSL3_VERSION, SSLv3_method, SSLv3_enc_data)
+IMPLEMENT_tls_meth_func(SSL3_VERSION, SSLv3_method)
 
 const SSL_METHOD *TLSv1_2_server_method(void)
 	{
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index 0a0c01b..e3c9393 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -410,7 +410,7 @@
 	/* decrypt in place in 'rr->input' */
 	rr->data=rr->input;
 
-	enc_err = s->method->ssl3_enc->enc(s,0);
+	enc_err = s->enc_method->enc(s,0);
 	/* enc_err is:
 	 *    0: (in non-constant time) if the record is publically invalid.
 	 *    1: if the padding is valid
@@ -477,7 +477,7 @@
 			mac = &rr->data[rr->length];
 			}
 
-		i=s->method->ssl3_enc->mac(s,md,0 /* not send */);
+		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)
@@ -788,7 +788,7 @@
 
 	if (mac_size != 0)
 		{
-		if (s->method->ssl3_enc->mac(s,&(p[wr->length + eivlen]),1) < 0)
+		if (s->enc_method->mac(s,&(p[wr->length + eivlen]),1) < 0)
 			goto err;
 		wr->length+=mac_size;
 		}
@@ -803,7 +803,7 @@
 		wr->length += eivlen;
 		}
 
-	if (s->method->ssl3_enc->enc(s, 1) < 1)
+	if (s->enc_method->enc(s, 1) < 1)
 		goto err;
 
 	/* record length after mac and block padding */
@@ -1366,10 +1366,10 @@
 			}
 
 		s->session->cipher=s->s3->tmp.new_cipher;
-		if (!s->method->ssl3_enc->setup_key_block(s)) return(0);
+		if (!s->enc_method->setup_key_block(s)) return(0);
 		}
 
-	if (!s->method->ssl3_enc->change_cipher_state(s,i))
+	if (!s->enc_method->change_cipher_state(s,i))
 		return(0);
 
 	return(1);
@@ -1378,7 +1378,7 @@
 int ssl3_send_alert(SSL *s, int level, int desc)
 	{
 	/* Map tls/ssl alert value to correct one */
-	desc=s->method->ssl3_enc->alert_value(desc);
+	desc=s->enc_method->alert_value(desc);
 	if (s->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION)
 		desc = SSL_AD_HANDSHAKE_FAILURE; /* SSL 3.0 does not have protocol_version alerts */
 	if (desc < 0) return -1;
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index 8a204ce..f9012cc 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -572,7 +572,7 @@
 		case SSL3_ST_SW_CHANGE_B:
 
 			s->session->cipher=s->s3->tmp.new_cipher;
-			if (!s->method->ssl3_enc->setup_key_block(s))
+			if (!s->enc_method->setup_key_block(s))
 				{ ret= -1; goto end; }
 
 			ret=ssl3_send_change_cipher_spec(s,
@@ -582,7 +582,7 @@
 			s->state=SSL3_ST_SW_FINISHED_A;
 			s->init_num=0;
 
-			if (!s->method->ssl3_enc->change_cipher_state(s,
+			if (!s->enc_method->change_cipher_state(s,
 				SSL3_CHANGE_CIPHER_SERVER_WRITE))
 				{
 				ret= -1;
@@ -595,8 +595,8 @@
 		case SSL3_ST_SW_FINISHED_B:
 			ret=ssl3_send_finished(s,
 				SSL3_ST_SW_FINISHED_A,SSL3_ST_SW_FINISHED_B,
-				s->method->ssl3_enc->server_finished_label,
-				s->method->ssl3_enc->server_finished_label_len);
+				s->enc_method->server_finished_label,
+				s->enc_method->server_finished_label_len);
 			if (ret <= 0) goto end;
 			s->state = SSL3_ST_SW_FLUSH;
 			if (s->hit)
@@ -865,6 +865,8 @@
 			s->version = version;
 			s->method = ssl3_get_method(version);
 			assert(s->method != NULL);
+			s->enc_method = ssl3_get_enc_method(version);
+			assert(s->enc_method != NULL);
 			}
 		}
 
@@ -2051,7 +2053,7 @@
 		}
 
 	/* Compute the master secret */
-	s->session->master_key_length = s->method->ssl3_enc
+	s->session->master_key_length = s->enc_method
 		->generate_master_secret(s,
 			s->session->master_key, premaster_secret, premaster_secret_len);
 	if (s->session->master_key_length == 0)
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 0456cf6..241bcc3 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -338,6 +338,8 @@
 
 	if (!s->method->ssl_new(s))
 		goto err;
+	s->enc_method = ssl3_get_enc_method(s->version);
+	assert(s->enc_method != NULL);
 
 	s->references=1;
 
@@ -1792,7 +1794,7 @@
 	if (s->version < TLS1_VERSION)
 		return -1;
 
-	return s->method->ssl3_enc->export_keying_material(s, out, olen, label,
+	return s->enc_method->export_keying_material(s, out, olen, label,
 							   llen, p, plen,
 							   use_context);
 	}
@@ -3069,6 +3071,27 @@
 		}
 	}
 
+const SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version)
+	{
+	switch (version)
+		{
+	case SSL3_VERSION:
+		return &SSLv3_enc_data;
+	case TLS1_VERSION:
+		return &TLSv1_enc_data;
+	case TLS1_1_VERSION:
+		return &TLSv1_1_enc_data;
+	case TLS1_2_VERSION:
+		return &TLSv1_2_enc_data;
+	case DTLS1_VERSION:
+		return &DTLSv1_enc_data;
+	case DTLS1_2_VERSION:
+		return &DTLSv1_2_enc_data;
+	default:
+		return NULL;
+		}
+	}
+
 uint16_t ssl3_get_max_server_version(const SSL *s)
 	{
 	if (SSL_IS_DTLS(s))
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 9940eb0..fdc06f7 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -366,20 +366,20 @@
 /* we have used 000001ff - 23 bits left to go */
 
 /* Check if an SSL structure is using DTLS */
-#define SSL_IS_DTLS(s)	(s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS)
+#define SSL_IS_DTLS(s)	(s->enc_method->enc_flags & SSL_ENC_FLAG_DTLS)
 /* See if we need explicit IV */
 #define SSL_USE_EXPLICIT_IV(s)	\
-		(s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_EXPLICIT_IV)
+		(s->enc_method->enc_flags & SSL_ENC_FLAG_EXPLICIT_IV)
 /* See if we use signature algorithms extension
  * and signature algorithm before signatures.
  */
 #define SSL_USE_SIGALGS(s)	\
-			(s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SIGALGS)
+			(s->enc_method->enc_flags & SSL_ENC_FLAG_SIGALGS)
 /* Allow TLS 1.2 ciphersuites: applies to DTLS 1.2 as well as TLS 1.2:
  * may apply to others in future.
  */
 #define SSL_USE_TLS1_2_CIPHERS(s)	\
-		(s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS)
+		(s->enc_method->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS)
 /* Determine if a client can use TLS 1.2 ciphersuites: can't rely on method
  * flags because it may not be set to correct version yet.
  */
@@ -597,12 +597,12 @@
 	void (*add_to_finished_hash)(SSL *s);
 	};
 
-#define SSL_HM_HEADER_LENGTH(s)	s->method->ssl3_enc->hhlen
+#define SSL_HM_HEADER_LENGTH(s)	s->enc_method->hhlen
 #define ssl_handshake_start(s) \
-	(((unsigned char *)s->init_buf->data) + s->method->ssl3_enc->hhlen)
+	(((unsigned char *)s->init_buf->data) + s->enc_method->hhlen)
 #define ssl_set_handshake_header(s, htype, len) \
-	s->method->ssl3_enc->set_handshake_header(s, htype, len)
-#define ssl_do_write(s)  s->method->ssl3_enc->do_write(s, add_to_finished_hash)
+	s->enc_method->set_handshake_header(s, htype, len)
+#define ssl_do_write(s)  s->enc_method->do_write(s, add_to_finished_hash)
 
 /* Values for enc_flags */
 
@@ -644,7 +644,7 @@
 extern const SSL3_ENC_METHOD DTLSv1_enc_data;
 extern const SSL3_ENC_METHOD DTLSv1_2_enc_data;
 
-#define IMPLEMENT_tls_meth_func(version, func_name, enc_data) \
+#define IMPLEMENT_tls_meth_func(version, func_name) \
 const SSL_METHOD *func_name(void)  \
 	{ \
 	static const SSL_METHOD func_name##_data= { \
@@ -669,7 +669,6 @@
 		ssl3_pending, \
 		ssl3_num_ciphers, \
 		ssl3_get_cipher, \
-		&enc_data, \
 		ssl_undefined_void_function, \
 		ssl3_callback_ctrl, \
 		ssl3_ctx_callback_ctrl, \
@@ -702,7 +701,6 @@
 	ssl_undefined_const_function, \
 	ssl3_num_ciphers, \
 	ssl3_get_cipher, \
-	&TLSv1_2_enc_data, \
 	ssl_undefined_void_function, \
 	ssl3_callback_ctrl, \
 	ssl3_ctx_callback_ctrl, \
@@ -710,7 +708,7 @@
 	return &func_name##_data; \
 	}
 
-#define IMPLEMENT_dtls1_meth_func(version, func_name, enc_data) \
+#define IMPLEMENT_dtls1_meth_func(version, func_name) \
 const SSL_METHOD *func_name(void)  \
 	{ \
 	static const SSL_METHOD func_name##_data= { \
@@ -735,7 +733,6 @@
 		ssl3_pending, \
 		ssl3_num_ciphers, \
 		dtls1_get_cipher, \
-		&enc_data, \
 		ssl_undefined_void_function, \
 		ssl3_callback_ctrl, \
 		ssl3_ctx_callback_ctrl, \
@@ -1076,6 +1073,10 @@
  * to |version|. */
 const SSL_METHOD *ssl3_get_method(uint16_t version);
 
+/* ssl3_get_enc_method returns the SSL3_ENC_METHOD corresponding to
+ * |version|. */
+const SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version);
+
 /* ssl3_get_max_server_version returns the maximum SSL/TLS version number
  * supported by |s| as a server, or zero if all versions are disabled. */
 uint16_t ssl3_get_max_server_version(const SSL *s);