From de2b05d4b4bdc8132abc4507b6d3e48eeba9340b Mon Sep 17 00:00:00 2001
From: beck <>
Date: Sat, 6 May 2017 22:24:58 +0000
Subject: Bring in an SSL_HANDSHAKE structure and commence the great shovelling
 ok jsing@, gcc@, regress@

---
 src/lib/libssl/d1_clnt.c              | 24 +++++++++---------
 src/lib/libssl/d1_srvr.c              | 24 +++++++++---------
 src/lib/libssl/s3_lib.c               |  6 ++---
 src/lib/libssl/ssl_both.c             |  4 +--
 src/lib/libssl/ssl_clnt.c             | 34 ++++++++++++-------------
 src/lib/libssl/ssl_lib.c              | 12 ++++-----
 src/lib/libssl/ssl_locl.h             | 24 +++++++++++-------
 src/lib/libssl/ssl_pkt.c              |  8 +++---
 src/lib/libssl/ssl_srvr.c             | 48 +++++++++++++++++------------------
 src/lib/libssl/t1_enc.c               | 34 ++++++++++++-------------
 src/lib/libssl/t1_lib.c               | 14 +++++-----
 src/regress/lib/libssl/unit/tls_prf.c |  4 +--
 12 files changed, 121 insertions(+), 115 deletions(-)

(limited to 'src')

diff --git a/src/lib/libssl/d1_clnt.c b/src/lib/libssl/d1_clnt.c
index 8e4c2586a3..802aa5cde0 100644
--- a/src/lib/libssl/d1_clnt.c
+++ b/src/lib/libssl/d1_clnt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: d1_clnt.c,v 1.74 2017/02/07 02:08:38 beck Exp $ */
+/* $OpenBSD: d1_clnt.c,v 1.75 2017/05/06 22:24:57 beck Exp $ */
 /*
  * DTLS implementation written by Nagendra Modadugu
  * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
@@ -268,7 +268,7 @@ dtls1_connect(SSL *s)
 
 			if (D1I(s)->send_cookie) {
 				s->internal->state = SSL3_ST_CW_FLUSH;
-				S3I(s)->tmp.next_state = SSL3_ST_CR_SRVR_HELLO_A;
+				S3I(s)->hs.next_state = SSL3_ST_CR_SRVR_HELLO_A;
 			} else
 				s->internal->state = SSL3_ST_CR_SRVR_HELLO_A;
 
@@ -324,7 +324,7 @@ dtls1_connect(SSL *s)
 				break;
 			}
 			/* Check if it is anon DH. */
-			if (!(S3I(s)->tmp.new_cipher->algorithm_auth &
+			if (!(S3I(s)->hs.new_cipher->algorithm_auth &
 			    SSL_aNULL)) {
 				ret = ssl3_get_server_certificate(s);
 				if (ret <= 0)
@@ -372,11 +372,11 @@ dtls1_connect(SSL *s)
 				goto end;
 			dtls1_stop_timer(s);
 			if (S3I(s)->tmp.cert_req)
-				S3I(s)->tmp.next_state = SSL3_ST_CW_CERT_A;
+				S3I(s)->hs.next_state = SSL3_ST_CW_CERT_A;
 			else
-				S3I(s)->tmp.next_state = SSL3_ST_CW_KEY_EXCH_A;
+				S3I(s)->hs.next_state = SSL3_ST_CW_KEY_EXCH_A;
 			s->internal->init_num = 0;
-			s->internal->state = S3I(s)->tmp.next_state;
+			s->internal->state = S3I(s)->hs.next_state;
 			break;
 
 		case SSL3_ST_CW_CERT_A:
@@ -435,7 +435,7 @@ dtls1_connect(SSL *s)
 			s->internal->state = SSL3_ST_CW_FINISHED_A;
 			s->internal->init_num = 0;
 
-			s->session->cipher = S3I(s)->tmp.new_cipher;
+			s->session->cipher = S3I(s)->hs.new_cipher;
 			if (!tls1_setup_key_block(s)) {
 				ret = -1;
 				goto end;
@@ -466,7 +466,7 @@ dtls1_connect(SSL *s)
 			/* clear flags */
 			s->s3->flags&= ~SSL3_FLAGS_POP_BUFFER;
 			if (s->internal->hit) {
-				S3I(s)->tmp.next_state = SSL_ST_OK;
+				S3I(s)->hs.next_state = SSL_ST_OK;
 				if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED) {
 					s->internal->state = SSL_ST_OK;
 					s->s3->flags |= SSL3_FLAGS_POP_BUFFER;
@@ -476,10 +476,10 @@ dtls1_connect(SSL *s)
 
 				/* Allow NewSessionTicket if ticket expected */
 				if (s->internal->tlsext_ticket_expected)
-					S3I(s)->tmp.next_state =
+					S3I(s)->hs.next_state =
 					    SSL3_ST_CR_SESSION_TICKET_A;
 				else
-					S3I(s)->tmp.next_state =
+					S3I(s)->hs.next_state =
 					    SSL3_ST_CR_FINISHED_A;
 			}
 			s->internal->init_num = 0;
@@ -527,14 +527,14 @@ dtls1_connect(SSL *s)
 				/* If the write error was fatal, stop trying */
 				if (!BIO_should_retry(s->wbio)) {
 					s->internal->rwstate = SSL_NOTHING;
-					s->internal->state = S3I(s)->tmp.next_state;
+					s->internal->state = S3I(s)->hs.next_state;
 				}
 
 				ret = -1;
 				goto end;
 			}
 			s->internal->rwstate = SSL_NOTHING;
-			s->internal->state = S3I(s)->tmp.next_state;
+			s->internal->state = S3I(s)->hs.next_state;
 			break;
 
 		case SSL_ST_OK:
diff --git a/src/lib/libssl/d1_srvr.c b/src/lib/libssl/d1_srvr.c
index 605f0a59ad..1ef8bce56b 100644
--- a/src/lib/libssl/d1_srvr.c
+++ b/src/lib/libssl/d1_srvr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: d1_srvr.c,v 1.86 2017/03/10 16:03:27 jsing Exp $ */
+/* $OpenBSD: d1_srvr.c,v 1.87 2017/05/06 22:24:57 beck Exp $ */
 /*
  * DTLS implementation written by Nagendra Modadugu
  * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
@@ -277,7 +277,7 @@ dtls1_accept(SSL *s)
 			ret = ssl3_send_hello_request(s);
 			if (ret <= 0)
 				goto end;
-			S3I(s)->tmp.next_state = SSL3_ST_SR_CLNT_HELLO_A;
+			S3I(s)->hs.next_state = SSL3_ST_SR_CLNT_HELLO_A;
 			s->internal->state = SSL3_ST_SW_FLUSH;
 			s->internal->init_num = 0;
 
@@ -335,7 +335,7 @@ dtls1_accept(SSL *s)
 			if (ret <= 0)
 				goto end;
 			s->internal->state = SSL3_ST_SW_FLUSH;
-			S3I(s)->tmp.next_state = SSL3_ST_SR_CLNT_HELLO_A;
+			S3I(s)->hs.next_state = SSL3_ST_SR_CLNT_HELLO_A;
 
 			/* HelloVerifyRequest resets Finished MAC */
 			if (!tls1_init_finished_mac(s)) {
@@ -366,7 +366,7 @@ dtls1_accept(SSL *s)
 		case SSL3_ST_SW_CERT_A:
 		case SSL3_ST_SW_CERT_B:
 			/* Check if it is anon DH. */
-			if (!(S3I(s)->tmp.new_cipher->algorithm_auth &
+			if (!(S3I(s)->hs.new_cipher->algorithm_auth &
 			    SSL_aNULL)) {
 				dtls1_start_timer(s);
 				ret = ssl3_send_server_certificate(s);
@@ -385,7 +385,7 @@ dtls1_accept(SSL *s)
 
 		case SSL3_ST_SW_KEY_EXCH_A:
 		case SSL3_ST_SW_KEY_EXCH_B:
-			alg_k = S3I(s)->tmp.new_cipher->algorithm_mkey;
+			alg_k = S3I(s)->hs.new_cipher->algorithm_mkey;
 
 			/* Only send if using a DH key exchange. */
 			if (alg_k & (SSL_kDHE|SSL_kECDHE)) {
@@ -422,7 +422,7 @@ dtls1_accept(SSL *s)
 			if (!(s->verify_mode & SSL_VERIFY_PEER) ||
 			    ((s->session->peer != NULL) &&
 			     (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) ||
-			    ((S3I(s)->tmp.new_cipher->algorithm_auth &
+			    ((S3I(s)->hs.new_cipher->algorithm_auth &
 			     SSL_aNULL) && !(s->verify_mode &
 			     SSL_VERIFY_FAIL_IF_NO_PEER_CERT))) {
 				/* no cert request */
@@ -446,7 +446,7 @@ dtls1_accept(SSL *s)
 			ret = ssl3_send_server_done(s);
 			if (ret <= 0)
 				goto end;
-			S3I(s)->tmp.next_state = SSL3_ST_SR_CERT_A;
+			S3I(s)->hs.next_state = SSL3_ST_SR_CERT_A;
 			s->internal->state = SSL3_ST_SW_FLUSH;
 			s->internal->init_num = 0;
 			break;
@@ -457,14 +457,14 @@ dtls1_accept(SSL *s)
 				/* If the write error was fatal, stop trying */
 				if (!BIO_should_retry(s->wbio)) {
 					s->internal->rwstate = SSL_NOTHING;
-					s->internal->state = S3I(s)->tmp.next_state;
+					s->internal->state = S3I(s)->hs.next_state;
 				}
 
 				ret = -1;
 				goto end;
 			}
 			s->internal->rwstate = SSL_NOTHING;
-			s->internal->state = S3I(s)->tmp.next_state;
+			s->internal->state = S3I(s)->hs.next_state;
 			break;
 
 		case SSL3_ST_SR_CERT_A:
@@ -590,7 +590,7 @@ dtls1_accept(SSL *s)
 		case SSL3_ST_SW_CHANGE_A:
 		case SSL3_ST_SW_CHANGE_B:
 
-			s->session->cipher = S3I(s)->tmp.new_cipher;
+			s->session->cipher = S3I(s)->hs.new_cipher;
 			if (!tls1_setup_key_block(s)) {
 				ret = -1;
 				goto end;
@@ -625,10 +625,10 @@ dtls1_accept(SSL *s)
 				goto end;
 			s->internal->state = SSL3_ST_SW_FLUSH;
 			if (s->internal->hit) {
-				S3I(s)->tmp.next_state = SSL3_ST_SR_FINISHED_A;
+				S3I(s)->hs.next_state = SSL3_ST_SR_FINISHED_A;
 
 			} else {
-				S3I(s)->tmp.next_state = SSL_ST_OK;
+				S3I(s)->hs.next_state = SSL_ST_OK;
 			}
 			s->internal->init_num = 0;
 			break;
diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c
index 0f05b8f2fe..f728eb7648 100644
--- a/src/lib/libssl/s3_lib.c
+++ b/src/lib/libssl/s3_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s3_lib.c,v 1.141 2017/05/06 20:37:24 jsing Exp $ */
+/* $OpenBSD: s3_lib.c,v 1.142 2017/05/06 22:24:57 beck Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -2504,7 +2504,7 @@ ssl3_get_req_cert_type(SSL *s, unsigned char *p)
 	int		ret = 0;
 	unsigned long	alg_k;
 
-	alg_k = S3I(s)->tmp.new_cipher->algorithm_mkey;
+	alg_k = S3I(s)->hs.new_cipher->algorithm_mkey;
 
 #ifndef OPENSSL_NO_GOST
 	if ((alg_k & SSL_kGOST)) {
@@ -2720,7 +2720,7 @@ ssl3_renegotiate_check(SSL *s)
 long
 ssl_get_algorithm2(SSL *s)
 {
-	long	alg2 = S3I(s)->tmp.new_cipher->algorithm2;
+	long	alg2 = S3I(s)->hs.new_cipher->algorithm2;
 
 	if (s->method->internal->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF &&
 	    alg2 == (SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF))
diff --git a/src/lib/libssl/ssl_both.c b/src/lib/libssl/ssl_both.c
index d1a0879b72..13c39e85b2 100644
--- a/src/lib/libssl/ssl_both.c
+++ b/src/lib/libssl/ssl_both.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_both.c,v 1.7 2017/03/05 14:24:12 jsing Exp $ */
+/* $OpenBSD: ssl_both.c,v 1.8 2017/05/06 22:24:57 beck Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -224,7 +224,7 @@ ssl3_take_mac(SSL *s)
 	 * If no new cipher setup return immediately: other functions will
 	 * set the appropriate error.
 	 */
-	if (S3I(s)->tmp.new_cipher == NULL)
+	if (S3I(s)->hs.new_cipher == NULL)
 		return;
 
 	if (s->internal->state & SSL_ST_CONNECT) {
diff --git a/src/lib/libssl/ssl_clnt.c b/src/lib/libssl/ssl_clnt.c
index 6fb5eca4b3..f6ca3e7f3c 100644
--- a/src/lib/libssl/ssl_clnt.c
+++ b/src/lib/libssl/ssl_clnt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_clnt.c,v 1.12 2017/04/10 06:09:32 jsing Exp $ */
+/* $OpenBSD: ssl_clnt.c,v 1.13 2017/05/06 22:24:57 beck Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -292,7 +292,7 @@ ssl3_connect(SSL *s)
 				break;
 			}
 			/* Check if it is anon DH/ECDH. */
-			if (!(S3I(s)->tmp.new_cipher->algorithm_auth &
+			if (!(S3I(s)->hs.new_cipher->algorithm_auth &
 			    SSL_aNULL)) {
 				ret = ssl3_get_server_certificate(s);
 				if (ret <= 0)
@@ -417,7 +417,7 @@ ssl3_connect(SSL *s)
 				s->internal->state = SSL3_ST_CW_FINISHED_A;
 			s->internal->init_num = 0;
 
-			s->session->cipher = S3I(s)->tmp.new_cipher;
+			s->session->cipher = S3I(s)->hs.new_cipher;
 			if (!tls1_setup_key_block(s)) {
 				ret = -1;
 				goto end;
@@ -453,7 +453,7 @@ ssl3_connect(SSL *s)
 			/* clear flags */
 			s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER;
 			if (s->internal->hit) {
-				S3I(s)->tmp.next_state = SSL_ST_OK;
+				S3I(s)->hs.next_state = SSL_ST_OK;
 				if (s->s3->flags &
 				    SSL3_FLAGS_DELAY_CLIENT_FINISHED) {
 					s->internal->state = SSL_ST_OK;
@@ -463,11 +463,11 @@ ssl3_connect(SSL *s)
 			} else {
 				/* Allow NewSessionTicket if ticket expected */
 				if (s->internal->tlsext_ticket_expected)
-					S3I(s)->tmp.next_state =
+					S3I(s)->hs.next_state =
 					    SSL3_ST_CR_SESSION_TICKET_A;
 				else
 
-				S3I(s)->tmp.next_state = SSL3_ST_CR_FINISHED_A;
+				S3I(s)->hs.next_state = SSL3_ST_CR_FINISHED_A;
 			}
 			s->internal->init_num = 0;
 			break;
@@ -512,7 +512,7 @@ ssl3_connect(SSL *s)
 				goto end;
 			}
 			s->internal->rwstate = SSL_NOTHING;
-			s->internal->state = S3I(s)->tmp.next_state;
+			s->internal->state = S3I(s)->hs.next_state;
 			break;
 
 		case SSL_ST_OK:
@@ -899,7 +899,7 @@ ssl3_get_server_hello(SSL *s)
 		SSLerror(s, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
 		goto f_err;
 	}
-	S3I(s)->tmp.new_cipher = cipher;
+	S3I(s)->hs.new_cipher = cipher;
 
 	if (!tls1_handshake_hash_init(s))
 		goto err;
@@ -908,7 +908,7 @@ ssl3_get_server_hello(SSL *s)
 	 * Don't digest cached records if no sigalgs: we may need them for
 	 * client authentication.
 	 */
-	alg_k = S3I(s)->tmp.new_cipher->algorithm_mkey;
+	alg_k = S3I(s)->hs.new_cipher->algorithm_mkey;
 	if (!(SSL_USE_SIGALGS(s) || (alg_k & SSL_kGOST)) &&
 	    !tls1_digest_cached_records(s)) {
 		al = SSL_AD_INTERNAL_ERROR;
@@ -1116,7 +1116,7 @@ ssl3_get_server_kex_dhe(SSL *s, EVP_PKEY **pkey, unsigned char **pp, long *nn)
 	long alg_a;
 	int al;
 
-	alg_a = S3I(s)->tmp.new_cipher->algorithm_auth;
+	alg_a = S3I(s)->hs.new_cipher->algorithm_auth;
 	sc = SSI(s)->sess_cert;
 
 	if (*nn < 0)
@@ -1283,7 +1283,7 @@ ssl3_get_server_kex_ecdhe(SSL *s, EVP_PKEY **pkey, unsigned char **pp, long *nn)
 	int nid;
 	int al;
 
-	alg_a = S3I(s)->tmp.new_cipher->algorithm_auth;
+	alg_a = S3I(s)->hs.new_cipher->algorithm_auth;
 	sc = SSI(s)->sess_cert;
 
 	if (*nn < 0)
@@ -1368,8 +1368,8 @@ ssl3_get_server_key_exchange(SSL *s)
 	const		 EVP_MD *md = NULL;
 	RSA		*rsa = NULL;
 
-	alg_k = S3I(s)->tmp.new_cipher->algorithm_mkey;
-	alg_a = S3I(s)->tmp.new_cipher->algorithm_auth;
+	alg_k = S3I(s)->hs.new_cipher->algorithm_mkey;
+	alg_a = S3I(s)->hs.new_cipher->algorithm_auth;
 
 	/*
 	 * Use same message size as in ssl3_get_certificate_request()
@@ -1590,7 +1590,7 @@ ssl3_get_certificate_request(SSL *s)
 	}
 
 	/* TLS does not like anon-DH with client cert */
-	if (S3I(s)->tmp.new_cipher->algorithm_auth & SSL_aNULL) {
+	if (S3I(s)->hs.new_cipher->algorithm_auth & SSL_aNULL) {
 		ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
 		SSLerror(s, SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER);
 		goto err;
@@ -2274,7 +2274,7 @@ ssl3_send_client_key_exchange(SSL *s)
 	memset(&cbb, 0, sizeof(cbb));
 
 	if (s->internal->state == SSL3_ST_CW_KEY_EXCH_A) {
-		alg_k = S3I(s)->tmp.new_cipher->algorithm_mkey;
+		alg_k = S3I(s)->hs.new_cipher->algorithm_mkey;
 
 		if ((sess_cert = SSI(s)->sess_cert) == NULL) {
 			ssl3_send_alert(s, SSL3_AL_FATAL,
@@ -2558,8 +2558,8 @@ ssl3_check_cert_and_algorithm(SSL *s)
 	SESS_CERT	*sc;
 	DH		*dh;
 
-	alg_k = S3I(s)->tmp.new_cipher->algorithm_mkey;
-	alg_a = S3I(s)->tmp.new_cipher->algorithm_auth;
+	alg_k = S3I(s)->hs.new_cipher->algorithm_mkey;
+	alg_a = S3I(s)->hs.new_cipher->algorithm_auth;
 
 	/* We don't have a certificate. */
 	if (alg_a & SSL_aNULL)
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c
index c49b79df0b..76b2f8a8c4 100644
--- a/src/lib/libssl/ssl_lib.c
+++ b/src/lib/libssl/ssl_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_lib.c,v 1.159 2017/05/06 20:37:25 jsing Exp $ */
+/* $OpenBSD: ssl_lib.c,v 1.160 2017/05/06 22:24:57 beck Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -2088,7 +2088,7 @@ ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
 int
 ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)
 {
-	const SSL_CIPHER	*cs = S3I(s)->tmp.new_cipher;
+	const SSL_CIPHER	*cs = S3I(s)->hs.new_cipher;
 	unsigned long		 alg_a;
 
 	alg_a = cs->algorithm_auth;
@@ -2116,9 +2116,9 @@ ssl_get_server_send_pkey(const SSL *s)
 	int		 i;
 
 	c = s->cert;
-	ssl_set_cert_masks(c, S3I(s)->tmp.new_cipher);
+	ssl_set_cert_masks(c, S3I(s)->hs.new_cipher);
 
-	alg_a = S3I(s)->tmp.new_cipher->algorithm_auth;
+	alg_a = S3I(s)->hs.new_cipher->algorithm_auth;
 
 	if (alg_a & SSL_aECDSA) {
 		i = SSL_PKEY_ECC;
@@ -2189,9 +2189,9 @@ ssl_get_auto_dh(SSL *s)
 
 	if (s->cert->dh_tmp_auto == 2) {
 		keylen = 1024;
-	} else if (S3I(s)->tmp.new_cipher->algorithm_auth & SSL_aNULL) {
+	} else if (S3I(s)->hs.new_cipher->algorithm_auth & SSL_aNULL) {
 		keylen = 1024;
-		if (S3I(s)->tmp.new_cipher->strength_bits == 256)
+		if (S3I(s)->hs.new_cipher->strength_bits == 256)
 			keylen = 3072;
 	} else {
 		if ((cpk = ssl_get_server_send_pkey(s)) == NULL)
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index b52b03149a..410fc04688 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_locl.h,v 1.179 2017/05/06 20:37:25 jsing Exp $ */
+/* $OpenBSD: ssl_locl.h,v 1.180 2017/05/06 22:24:58 beck Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -431,6 +431,18 @@ typedef struct ssl_session_internal_st {
 } SSL_SESSION_INTERNAL;
 #define SSI(s) (s->session->internal)
 
+typedef struct ssl_handshake_st {
+	/* used when SSL_ST_FLUSH_DATA is entered */
+	int next_state;
+
+	/*  new_cipher is the cipher being negotiated in this handshake. */
+	const SSL_CIPHER *new_cipher;
+
+	/* key_block is the record-layer key block for TLS 1.2 and earlier. */
+	int key_block_len;
+	unsigned char *key_block;
+} SSL_HANDSHAKE;
+
 typedef struct ssl_ctx_internal_st {
 	uint16_t min_version;
 	uint16_t max_version;
@@ -824,6 +836,8 @@ typedef struct ssl3_state_internal_st {
 
 	int in_read_app_data;
 
+	SSL_HANDSHAKE hs;
+
 	struct	{
 		/* actually only needs to be 16+20 */
 		unsigned char cert_verify_md[EVP_MAX_MD_SIZE*2];
@@ -837,17 +851,12 @@ typedef struct ssl3_state_internal_st {
 		unsigned long message_size;
 		int message_type;
 
-		/* used to hold the new cipher we are going to use */
-		const SSL_CIPHER *new_cipher;
 		DH *dh;
 
 		EC_KEY *ecdh; /* holds short lived ECDH key */
 
 		uint8_t *x25519;
 
-		/* used when SSL_ST_FLUSH_DATA is entered */
-		int next_state;
-
 		int reuse_message;
 
 		/* used for certificate requests */
@@ -856,9 +865,6 @@ typedef struct ssl3_state_internal_st {
 		char ctype[SSL3_CT_NUMBER];
 		STACK_OF(X509_NAME) *ca_names;
 
-		int key_block_length;
-		unsigned char *key_block;
-
 		const EVP_CIPHER *new_sym_enc;
 		const EVP_AEAD *new_aead;
 		const EVP_MD *new_hash;
diff --git a/src/lib/libssl/ssl_pkt.c b/src/lib/libssl/ssl_pkt.c
index f49cc45efd..953f3c118f 100644
--- a/src/lib/libssl/ssl_pkt.c
+++ b/src/lib/libssl/ssl_pkt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_pkt.c,v 1.10 2017/02/07 02:08:38 beck Exp $ */
+/* $OpenBSD: ssl_pkt.c,v 1.11 2017/05/06 22:24:58 beck Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -1235,7 +1235,7 @@ start:
 		}
 
 		/* Check we have a cipher to change to */
-		if (S3I(s)->tmp.new_cipher == NULL) {
+		if (S3I(s)->hs.new_cipher == NULL) {
 			al = SSL_AD_UNEXPECTED_MESSAGE;
 			SSLerror(s, SSL_R_CCS_RECEIVED_EARLY);
 			goto f_err;
@@ -1360,14 +1360,14 @@ ssl3_do_change_cipher_spec(SSL *s)
 	else
 		i = SSL3_CHANGE_CIPHER_CLIENT_READ;
 
-	if (S3I(s)->tmp.key_block == NULL) {
+	if (S3I(s)->hs.key_block == NULL) {
 		if (s->session == NULL || s->session->master_key_length == 0) {
 			/* might happen if dtls1_read_bytes() calls this */
 			SSLerror(s, SSL_R_CCS_RECEIVED_EARLY);
 			return (0);
 		}
 
-		s->session->cipher = S3I(s)->tmp.new_cipher;
+		s->session->cipher = S3I(s)->hs.new_cipher;
 		if (!tls1_setup_key_block(s))
 			return (0);
 	}
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c
index ea1aed26b3..35a9ace527 100644
--- a/src/lib/libssl/ssl_srvr.c
+++ b/src/lib/libssl/ssl_srvr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_srvr.c,v 1.15 2017/04/29 23:38:49 jsing Exp $ */
+/* $OpenBSD: ssl_srvr.c,v 1.16 2017/05/06 22:24:58 beck Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -275,7 +275,7 @@ ssl3_accept(SSL *s)
 			ret = ssl3_send_hello_request(s);
 			if (ret <= 0)
 				goto end;
-			S3I(s)->tmp.next_state = SSL3_ST_SW_HELLO_REQ_C;
+			S3I(s)->hs.next_state = SSL3_ST_SW_HELLO_REQ_C;
 			s->internal->state = SSL3_ST_SW_FLUSH;
 			s->internal->init_num = 0;
 
@@ -324,7 +324,7 @@ ssl3_accept(SSL *s)
 		case SSL3_ST_SW_CERT_A:
 		case SSL3_ST_SW_CERT_B:
 			/* Check if it is anon DH or anon ECDH. */
-			if (!(S3I(s)->tmp.new_cipher->algorithm_auth &
+			if (!(S3I(s)->hs.new_cipher->algorithm_auth &
 			    SSL_aNULL)) {
 				ret = ssl3_send_server_certificate(s);
 				if (ret <= 0)
@@ -342,7 +342,7 @@ ssl3_accept(SSL *s)
 
 		case SSL3_ST_SW_KEY_EXCH_A:
 		case SSL3_ST_SW_KEY_EXCH_B:
-			alg_k = S3I(s)->tmp.new_cipher->algorithm_mkey;
+			alg_k = S3I(s)->hs.new_cipher->algorithm_mkey;
 
 			/*
 			 * Only send if using a DH key exchange.
@@ -385,7 +385,7 @@ ssl3_accept(SSL *s)
 			if (!(s->verify_mode & SSL_VERIFY_PEER) ||
 			    ((s->session->peer != NULL) &&
 			     (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) ||
-			    ((S3I(s)->tmp.new_cipher->algorithm_auth &
+			    ((S3I(s)->hs.new_cipher->algorithm_auth &
 			     SSL_aNULL) && !(s->verify_mode &
 			     SSL_VERIFY_FAIL_IF_NO_PEER_CERT))) {
 				/* No cert request */
@@ -413,7 +413,7 @@ ssl3_accept(SSL *s)
 			ret = ssl3_send_server_done(s);
 			if (ret <= 0)
 				goto end;
-			S3I(s)->tmp.next_state = SSL3_ST_SR_CERT_A;
+			S3I(s)->hs.next_state = SSL3_ST_SR_CERT_A;
 			s->internal->state = SSL3_ST_SW_FLUSH;
 			s->internal->init_num = 0;
 			break;
@@ -438,7 +438,7 @@ ssl3_accept(SSL *s)
 			}
 			s->internal->rwstate = SSL_NOTHING;
 
-			s->internal->state = S3I(s)->tmp.next_state;
+			s->internal->state = S3I(s)->hs.next_state;
 			break;
 
 		case SSL3_ST_SR_CERT_A:
@@ -457,7 +457,7 @@ ssl3_accept(SSL *s)
 			ret = ssl3_get_client_key_exchange(s);
 			if (ret <= 0)
 				goto end;
-			alg_k = S3I(s)->tmp.new_cipher->algorithm_mkey;
+			alg_k = S3I(s)->hs.new_cipher->algorithm_mkey;
 			if (ret == 2) {
 				/*
 				 * For the ECDH ciphersuites when
@@ -579,7 +579,7 @@ ssl3_accept(SSL *s)
 		case SSL3_ST_SW_CHANGE_A:
 		case SSL3_ST_SW_CHANGE_B:
 
-			s->session->cipher = S3I(s)->tmp.new_cipher;
+			s->session->cipher = S3I(s)->hs.new_cipher;
 			if (!tls1_setup_key_block(s)) {
 				ret = -1;
 				goto end;
@@ -613,13 +613,13 @@ ssl3_accept(SSL *s)
 			if (s->internal->hit) {
 				if (S3I(s)->next_proto_neg_seen) {
 					s->s3->flags |= SSL3_FLAGS_CCS_OK;
-					S3I(s)->tmp.next_state =
+					S3I(s)->hs.next_state =
 					    SSL3_ST_SR_NEXT_PROTO_A;
 				} else
-					S3I(s)->tmp.next_state =
+					S3I(s)->hs.next_state =
 					    SSL3_ST_SR_FINISHED_A;
 			} else
-				S3I(s)->tmp.next_state = SSL_ST_OK;
+				S3I(s)->hs.next_state = SSL_ST_OK;
 			s->internal->init_num = 0;
 			break;
 
@@ -1024,15 +1024,15 @@ ssl3_get_client_hello(SSL *s)
 			SSLerror(s, SSL_R_NO_SHARED_CIPHER);
 			goto f_err;
 		}
-		S3I(s)->tmp.new_cipher = c;
+		S3I(s)->hs.new_cipher = c;
 	} else {
-		S3I(s)->tmp.new_cipher = s->session->cipher;
+		S3I(s)->hs.new_cipher = s->session->cipher;
 	}
 
 	if (!tls1_handshake_hash_init(s))
 		goto err;
 
-	alg_k = S3I(s)->tmp.new_cipher->algorithm_mkey;
+	alg_k = S3I(s)->hs.new_cipher->algorithm_mkey;
 	if (!(SSL_USE_SIGALGS(s) || (alg_k & SSL_kGOST)) ||
 	    !(s->verify_mode & SSL_VERIFY_PEER)) {
 		if (!tls1_digest_cached_records(s)) {
@@ -1050,7 +1050,7 @@ ssl3_get_client_hello(SSL *s)
 	 * ssl version is set	- sslv3
 	 * s->session		- The ssl session has been setup.
 	 * s->internal->hit		- session reuse flag
-	 * s->tmp.new_cipher	- the new cipher to use.
+	 * s->hs.new_cipher	- the new cipher to use.
 	 */
 
 	/* Handles TLS extensions that we couldn't check earlier */
@@ -1134,7 +1134,7 @@ ssl3_send_server_hello(SSL *s)
 
 		/* Cipher suite. */
 		if (!CBB_add_u16(&cbb,
-		    ssl3_cipher_get_value(S3I(s)->tmp.new_cipher)))
+		    ssl3_cipher_get_value(S3I(s)->hs.new_cipher)))
 			goto err;
 
 		/* Compression method. */
@@ -1207,7 +1207,7 @@ ssl3_send_server_kex_dhe(SSL *s, CBB *cbb)
 
 	if (dhp == NULL && s->cert->dh_tmp_cb != NULL)
 		dhp = s->cert->dh_tmp_cb(s, 0,
-		    SSL_C_PKEYLENGTH(S3I(s)->tmp.new_cipher));
+		    SSL_C_PKEYLENGTH(S3I(s)->hs.new_cipher));
 
 	if (dhp == NULL) {
 		al = SSL_AD_HANDSHAKE_FAILURE;
@@ -1282,7 +1282,7 @@ ssl3_send_server_kex_ecdhe_ecp(SSL *s, int nid, CBB *cbb)
 			ecdhp = EC_KEY_new_by_curve_name(nid);
 	} else if (ecdhp == NULL && s->cert->ecdh_tmp_cb != NULL) {
 		ecdhp = s->cert->ecdh_tmp_cb(s, 0,
-		    SSL_C_PKEYLENGTH(S3I(s)->tmp.new_cipher));
+		    SSL_C_PKEYLENGTH(S3I(s)->hs.new_cipher));
 	}
 	if (ecdhp == NULL) {
 		al = SSL_AD_HANDSHAKE_FAILURE;
@@ -1458,7 +1458,7 @@ ssl3_send_server_key_exchange(SSL *s)
 
 	EVP_MD_CTX_init(&md_ctx);
 	if (s->internal->state == SSL3_ST_SW_KEY_EXCH_A) {
-		type = S3I(s)->tmp.new_cipher->algorithm_mkey;
+		type = S3I(s)->hs.new_cipher->algorithm_mkey;
 
 		buf = s->internal->init_buf;
 
@@ -1480,9 +1480,9 @@ ssl3_send_server_key_exchange(SSL *s)
 		if (!CBB_finish(&cbb, &params, &params_len))
 			goto err;
 
-		if (!(S3I(s)->tmp.new_cipher->algorithm_auth & SSL_aNULL)) {
+		if (!(S3I(s)->hs.new_cipher->algorithm_auth & SSL_aNULL)) {
 			if ((pkey = ssl_get_sign_pkey(
-			    s, S3I(s)->tmp.new_cipher, &md)) == NULL) {
+			    s, S3I(s)->hs.new_cipher, &md)) == NULL) {
 				al = SSL_AD_DECODE_ERROR;
 				goto f_err;
 			}
@@ -2028,7 +2028,7 @@ ssl3_get_client_kex_gost(SSL *s, unsigned char *p, long n)
 	int ret = 0;
 
 	/* Get our certificate private key*/
-	alg_a = S3I(s)->tmp.new_cipher->algorithm_auth;
+	alg_a = S3I(s)->hs.new_cipher->algorithm_auth;
 	if (alg_a & SSL_aGOST01)
 		pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey;
 
@@ -2105,7 +2105,7 @@ ssl3_get_client_key_exchange(SSL *s)
 
 	p = (unsigned char *)s->internal->init_msg;
 
-	alg_k = S3I(s)->tmp.new_cipher->algorithm_mkey;
+	alg_k = S3I(s)->hs.new_cipher->algorithm_mkey;
 
 	if (alg_k & SSL_kRSA) {
 		if (ssl3_get_client_kex_rsa(s, p, n) != 1)
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c
index ce57235cea..9598613516 100644
--- a/src/lib/libssl/t1_enc.c
+++ b/src/lib/libssl/t1_enc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: t1_enc.c,v 1.108 2017/04/10 16:48:43 jsing Exp $ */
+/* $OpenBSD: t1_enc.c,v 1.109 2017/05/06 22:24:58 beck Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -152,9 +152,9 @@ int tls1_PRF(SSL *s, const unsigned char *secret, size_t secret_len,
 void
 tls1_cleanup_key_block(SSL *s)
 {
-	freezero(S3I(s)->tmp.key_block, S3I(s)->tmp.key_block_length);
-	S3I(s)->tmp.key_block = NULL;
-	S3I(s)->tmp.key_block_length = 0;
+	freezero(S3I(s)->hs.key_block, S3I(s)->hs.key_block_len);
+	S3I(s)->hs.key_block = NULL;
+	S3I(s)->hs.key_block_len = 0;
 }
 
 int
@@ -417,10 +417,10 @@ tls1_change_cipher_state_aead(SSL *s, char is_read, const unsigned char *key,
 	aead_ctx->fixed_nonce_len = iv_len;
 	aead_ctx->variable_nonce_len = 8;  /* always the case, currently. */
 	aead_ctx->variable_nonce_in_record =
-	    (S3I(s)->tmp.new_cipher->algorithm2 &
+	    (S3I(s)->hs.new_cipher->algorithm2 &
 	    SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_IN_RECORD) != 0;
 	aead_ctx->xor_fixed_nonce =
-	    S3I(s)->tmp.new_cipher->algorithm_enc == SSL_CHACHA20POLY1305;
+	    S3I(s)->hs.new_cipher->algorithm_enc == SSL_CHACHA20POLY1305;
 	aead_ctx->tag_len = EVP_AEAD_max_overhead(aead);
 
 	if (aead_ctx->xor_fixed_nonce) {
@@ -464,7 +464,7 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read, char use_client_keys,
 	mac_type = S3I(s)->tmp.new_mac_pkey_type;
 
 	if (is_read) {
-		if (S3I(s)->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
+		if (S3I(s)->hs.new_cipher->algorithm2 & TLS1_STREAM_MAC)
 			s->internal->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM;
 		else
 			s->internal->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM;
@@ -481,7 +481,7 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read, char use_client_keys,
 			goto err;
 		s->read_hash = mac_ctx;
 	} else {
-		if (S3I(s)->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
+		if (S3I(s)->hs.new_cipher->algorithm2 & TLS1_STREAM_MAC)
 			s->internal->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM;
 		else
 			s->internal->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM;
@@ -528,15 +528,15 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read, char use_client_keys,
 		    mac_secret_size, (unsigned char *)mac_secret);
 	}
 
-	if (S3I(s)->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT) {
+	if (S3I(s)->hs.new_cipher->algorithm_enc == SSL_eGOST2814789CNT) {
 		int nid;
-		if (S3I(s)->tmp.new_cipher->algorithm2 & SSL_HANDSHAKE_MAC_GOST94)
+		if (S3I(s)->hs.new_cipher->algorithm2 & SSL_HANDSHAKE_MAC_GOST94)
 			nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet;
 		else
 			nid = NID_id_tc26_gost_28147_param_Z;
 
 		EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GOST_SET_SBOX, nid, 0);
-		if (S3I(s)->tmp.new_cipher->algorithm_mac == SSL_GOST89MAC)
+		if (S3I(s)->hs.new_cipher->algorithm_mac == SSL_GOST89MAC)
 			EVP_MD_CTX_ctrl(mac_ctx, EVP_MD_CTRL_GOST_SET_SBOX, nid, 0);
 	}
 
@@ -591,7 +591,7 @@ tls1_change_cipher_state(SSL *s, int which)
 
 	if (aead != NULL) {
 		key_len = EVP_AEAD_key_length(aead);
-		iv_len = SSL_CIPHER_AEAD_FIXED_NONCE_LEN(S3I(s)->tmp.new_cipher);
+		iv_len = SSL_CIPHER_AEAD_FIXED_NONCE_LEN(S3I(s)->hs.new_cipher);
 	} else {
 		key_len = EVP_CIPHER_key_length(cipher);
 		iv_len = EVP_CIPHER_iv_length(cipher);
@@ -603,7 +603,7 @@ tls1_change_cipher_state(SSL *s, int which)
 
 	mac_secret_size = s->s3->tmp.new_mac_secret_size;
 
-	key_block = S3I(s)->tmp.key_block;
+	key_block = S3I(s)->hs.key_block;
 	client_write_mac_secret = key_block;
 	key_block += mac_secret_size;
 	server_write_mac_secret = key_block;
@@ -627,7 +627,7 @@ tls1_change_cipher_state(SSL *s, int which)
 		iv = server_write_iv;
 	}
 
-	if (key_block - S3I(s)->tmp.key_block != S3I(s)->tmp.key_block_length) {
+	if (key_block - S3I(s)->hs.key_block != S3I(s)->hs.key_block_len) {
 		SSLerror(s, ERR_R_INTERNAL_ERROR);
 		goto err2;
 	}
@@ -663,7 +663,7 @@ tls1_setup_key_block(SSL *s)
 	const EVP_MD *mac = NULL;
 	int ret = 0;
 
-	if (S3I(s)->tmp.key_block_length != 0)
+	if (S3I(s)->hs.key_block_len != 0)
 		return (1);
 
 	if (s->session->cipher &&
@@ -703,8 +703,8 @@ tls1_setup_key_block(SSL *s)
 	}
 	key_block_len = (mac_secret_size + key_len + iv_len) * 2;
 
-	S3I(s)->tmp.key_block_length = key_block_len;
-	S3I(s)->tmp.key_block = key_block;
+	S3I(s)->hs.key_block_len = key_block_len;
+	S3I(s)->hs.key_block = key_block;
 
 	if (!tls1_generate_key_block(s, key_block, key_block_len))
 		goto err;
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c
index a42e414dec..2cb47a215c 100644
--- a/src/lib/libssl/t1_lib.c
+++ b/src/lib/libssl/t1_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: t1_lib.c,v 1.115 2017/02/07 02:08:38 beck Exp $ */
+/* $OpenBSD: t1_lib.c,v 1.116 2017/05/06 22:24:58 beck Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -998,8 +998,8 @@ ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
 	unsigned char *ret = p;
 	int next_proto_neg_seen;
 
-	alg_a = S3I(s)->tmp.new_cipher->algorithm_auth;
-	alg_k = S3I(s)->tmp.new_cipher->algorithm_mkey;
+	alg_a = S3I(s)->hs.new_cipher->algorithm_auth;
+	alg_k = S3I(s)->hs.new_cipher->algorithm_mkey;
 	using_ecc = ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA)) &&
 	    SSI(s)->tlsext_ecpointformatlist != NULL;
 
@@ -1107,8 +1107,8 @@ ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
 	}
 #endif
 
-	if (((S3I(s)->tmp.new_cipher->id & 0xFFFF) == 0x80 ||
-	    (S3I(s)->tmp.new_cipher->id & 0xFFFF) == 0x81) &&
+	if (((S3I(s)->hs.new_cipher->id & 0xFFFF) == 0x80 ||
+	    (S3I(s)->hs.new_cipher->id & 0xFFFF) == 0x81) &&
 	    (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG)) {
 		static const unsigned char cryptopro_ext[36] = {
 			0xfd, 0xe8, /*65000*/
@@ -1986,8 +1986,8 @@ ssl_check_serverhello_tlsext(SSL *s)
 	 * suite, then if server returns an EC point formats lists extension
 	 * it must contain uncompressed.
 	 */
-	unsigned long alg_k = S3I(s)->tmp.new_cipher->algorithm_mkey;
-	unsigned long alg_a = S3I(s)->tmp.new_cipher->algorithm_auth;
+	unsigned long alg_k = S3I(s)->hs.new_cipher->algorithm_mkey;
+	unsigned long alg_a = S3I(s)->hs.new_cipher->algorithm_auth;
 	if ((s->internal->tlsext_ecpointformatlist != NULL) &&
 	    (s->internal->tlsext_ecpointformatlist_length > 0) &&
 	    (SSI(s)->tlsext_ecpointformatlist != NULL) &&
diff --git a/src/regress/lib/libssl/unit/tls_prf.c b/src/regress/lib/libssl/unit/tls_prf.c
index 5040ba2ce3..2eacb12af3 100644
--- a/src/regress/lib/libssl/unit/tls_prf.c
+++ b/src/regress/lib/libssl/unit/tls_prf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_prf.c,v 1.3 2017/03/25 13:37:40 jsing Exp $ */
+/* $OpenBSD: tls_prf.c,v 1.4 2017/05/06 22:24:58 beck Exp $ */
 /*
  * Copyright (c) 2017 Joel Sing <jsing@openbsd.org>
  *
@@ -197,7 +197,7 @@ do_tls_prf_test(int test_no, struct tls_prf_test *tpt)
 		goto failure;
 	}
 
-	S3I(ssl)->tmp.new_cipher = cipher;
+	S3I(ssl)->hs.new_cipher = cipher;
 
 	for (len = 1; len <= TLS_PRF_OUT_LEN; len++) {
 		memset(out, 'A', TLS_PRF_OUT_LEN);
-- 
cgit v1.2.3-55-g6feb