summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorjsing <>2017-03-05 14:39:53 +0000
committerjsing <>2017-03-05 14:39:53 +0000
commite04ca894aa08b4b01dbc7ead7524d8026ce8f3be (patch)
tree4868a41992758cf1a7f9ffdaf1b940ee7bcceb4c /src/lib
parentb7e97f3829f43765f12691c1665b5e6017d75d28 (diff)
downloadopenbsd-e04ca894aa08b4b01dbc7ead7524d8026ce8f3be.tar.gz
openbsd-e04ca894aa08b4b01dbc7ead7524d8026ce8f3be.tar.bz2
openbsd-e04ca894aa08b4b01dbc7ead7524d8026ce8f3be.zip
Provide a rolling handshake hash that commences as soon as the cipher
suite has been selected, and convert the final finish MAC to use this handshake hash. This is a first step towards cleaning up the current handshake buffer/digest code. ok beck@ inoguchi@
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libssl/Makefile4
-rw-r--r--src/lib/libssl/s3_lib.c7
-rw-r--r--src/lib/libssl/ssl_ciph.c30
-rw-r--r--src/lib/libssl/ssl_clnt.c5
-rw-r--r--src/lib/libssl/ssl_locl.h26
-rw-r--r--src/lib/libssl/ssl_srvr.c5
-rw-r--r--src/lib/libssl/t1_enc.c60
-rw-r--r--src/lib/libssl/t1_hash.c110
8 files changed, 193 insertions, 54 deletions
diff --git a/src/lib/libssl/Makefile b/src/lib/libssl/Makefile
index 1fa49e86df..b1e67ed9ac 100644
--- a/src/lib/libssl/Makefile
+++ b/src/lib/libssl/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.31 2017/01/26 09:16:01 jsing Exp $ 1# $OpenBSD: Makefile,v 1.32 2017/03/05 14:39:53 jsing Exp $
2 2
3.include <bsd.own.mk> 3.include <bsd.own.mk>
4.ifndef NOMAN 4.ifndef NOMAN
@@ -25,7 +25,7 @@ SYMBOL_LIST= ${.CURDIR}/Symbols.list
25 25
26SRCS= \ 26SRCS= \
27 ssl_srvr.c ssl_clnt.c s3_lib.c ssl_pkt.c ssl_both.c \ 27 ssl_srvr.c ssl_clnt.c s3_lib.c ssl_pkt.c ssl_both.c \
28 t1_meth.c t1_srvr.c t1_clnt.c t1_lib.c t1_enc.c \ 28 t1_meth.c t1_srvr.c t1_clnt.c t1_lib.c t1_enc.c t1_hash.c \
29 d1_meth.c d1_srvr.c d1_clnt.c d1_lib.c d1_pkt.c \ 29 d1_meth.c d1_srvr.c d1_clnt.c d1_lib.c d1_pkt.c \
30 d1_both.c d1_enc.c d1_srtp.c \ 30 d1_both.c d1_enc.c d1_srtp.c \
31 ssl_lib.c ssl_cert.c ssl_sess.c \ 31 ssl_lib.c ssl_cert.c ssl_sess.c \
diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c
index 3f09834ab1..d6bf6a4574 100644
--- a/src/lib/libssl/s3_lib.c
+++ b/src/lib/libssl/s3_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: s3_lib.c,v 1.136 2017/03/04 16:32:00 jsing Exp $ */ 1/* $OpenBSD: s3_lib.c,v 1.137 2017/03/05 14:39:53 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -1839,8 +1839,12 @@ ssl3_free(SSL *s)
1839 free(S3I(s)->tmp.x25519); 1839 free(S3I(s)->tmp.x25519);
1840 1840
1841 sk_X509_NAME_pop_free(S3I(s)->tmp.ca_names, X509_NAME_free); 1841 sk_X509_NAME_pop_free(S3I(s)->tmp.ca_names, X509_NAME_free);
1842
1842 BIO_free(S3I(s)->handshake_buffer); 1843 BIO_free(S3I(s)->handshake_buffer);
1844
1843 tls1_free_digest_list(s); 1845 tls1_free_digest_list(s);
1846 tls1_handshake_hash_free(s);
1847
1844 free(S3I(s)->alpn_selected); 1848 free(S3I(s)->alpn_selected);
1845 1849
1846 explicit_bzero(S3I(s), sizeof(*S3I(s))); 1850 explicit_bzero(S3I(s), sizeof(*S3I(s)));
@@ -1881,6 +1885,7 @@ ssl3_clear(SSL *s)
1881 S3I(s)->handshake_buffer = NULL; 1885 S3I(s)->handshake_buffer = NULL;
1882 1886
1883 tls1_free_digest_list(s); 1887 tls1_free_digest_list(s);
1888 tls1_handshake_hash_free(s);
1884 1889
1885 free(S3I(s)->alpn_selected); 1890 free(S3I(s)->alpn_selected);
1886 S3I(s)->alpn_selected = NULL; 1891 S3I(s)->alpn_selected = NULL;
diff --git a/src/lib/libssl/ssl_ciph.c b/src/lib/libssl/ssl_ciph.c
index 3e991fa577..da48765aba 100644
--- a/src/lib/libssl/ssl_ciph.c
+++ b/src/lib/libssl/ssl_ciph.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_ciph.c,v 1.94 2017/02/21 15:28:27 jsing Exp $ */ 1/* $OpenBSD: ssl_ciph.c,v 1.95 2017/03/05 14:39:53 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -719,6 +719,34 @@ ssl_get_handshake_digest(int idx, long *mask, const EVP_MD **md)
719 return 1; 719 return 1;
720} 720}
721 721
722int
723ssl_get_handshake_evp_md(SSL *s, const EVP_MD **md)
724{
725 *md = NULL;
726
727 switch (ssl_get_algorithm2(s) & SSL_HANDSHAKE_MAC_MASK) {
728 case SSL_HANDSHAKE_MAC_DEFAULT:
729 *md = EVP_md5_sha1();
730 return 1;
731 case SSL_HANDSHAKE_MAC_GOST94:
732 *md = EVP_gostr341194();
733 return 1;
734 case SSL_HANDSHAKE_MAC_SHA256:
735 *md = EVP_sha256();
736 return 1;
737 case SSL_HANDSHAKE_MAC_SHA384:
738 *md = EVP_sha384();
739 return 1;
740 case SSL_HANDSHAKE_MAC_STREEBOG256:
741 *md = EVP_streebog256();
742 return 1;
743 default:
744 break;
745 }
746
747 return 0;
748}
749
722#define ITEM_SEP(a) \ 750#define ITEM_SEP(a) \
723 (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ',')) 751 (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ','))
724 752
diff --git a/src/lib/libssl/ssl_clnt.c b/src/lib/libssl/ssl_clnt.c
index f46b66c372..8dd30e87fb 100644
--- a/src/lib/libssl/ssl_clnt.c
+++ b/src/lib/libssl/ssl_clnt.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_clnt.c,v 1.9 2017/03/05 14:24:12 jsing Exp $ */ 1/* $OpenBSD: ssl_clnt.c,v 1.10 2017/03/05 14:39:53 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -901,6 +901,9 @@ ssl3_get_server_hello(SSL *s)
901 } 901 }
902 S3I(s)->tmp.new_cipher = cipher; 902 S3I(s)->tmp.new_cipher = cipher;
903 903
904 if (!tls1_handshake_hash_init(s))
905 goto err;
906
904 /* 907 /*
905 * Don't digest cached records if no sigalgs: we may need them for 908 * Don't digest cached records if no sigalgs: we may need them for
906 * client authentication. 909 * client authentication.
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index deabb58894..3f5d6fad20 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_locl.h,v 1.176 2017/03/04 16:32:00 jsing Exp $ */ 1/* $OpenBSD: ssl_locl.h,v 1.177 2017/03/05 14:39:53 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -259,12 +259,13 @@ __BEGIN_HIDDEN_DECLS
259 259
260/* Bits for algorithm2 (handshake digests and other extra flags) */ 260/* Bits for algorithm2 (handshake digests and other extra flags) */
261 261
262#define SSL_HANDSHAKE_MAC_MD5 0x10 262#define SSL_HANDSHAKE_MAC_MASK 0xff0
263#define SSL_HANDSHAKE_MAC_SHA 0x20 263#define SSL_HANDSHAKE_MAC_MD5 0x010
264#define SSL_HANDSHAKE_MAC_GOST94 0x40 264#define SSL_HANDSHAKE_MAC_SHA 0x020
265#define SSL_HANDSHAKE_MAC_SHA256 0x80 265#define SSL_HANDSHAKE_MAC_GOST94 0x040
266#define SSL_HANDSHAKE_MAC_SHA384 0x100 266#define SSL_HANDSHAKE_MAC_SHA256 0x080
267#define SSL_HANDSHAKE_MAC_STREEBOG256 0x200 267#define SSL_HANDSHAKE_MAC_SHA384 0x100
268#define SSL_HANDSHAKE_MAC_STREEBOG256 0x200
268#define SSL_HANDSHAKE_MAC_DEFAULT (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA) 269#define SSL_HANDSHAKE_MAC_DEFAULT (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA)
269 270
270/* When adding new digest in the ssl_ciph.c and increment SSM_MD_NUM_IDX 271/* When adding new digest in the ssl_ciph.c and increment SSM_MD_NUM_IDX
@@ -808,6 +809,10 @@ typedef struct ssl3_state_internal_st {
808 * and freed and MD_CTX-es for all required digests are stored in 809 * and freed and MD_CTX-es for all required digests are stored in
809 * this array */ 810 * this array */
810 EVP_MD_CTX **handshake_dgst; 811 EVP_MD_CTX **handshake_dgst;
812
813 /* Rolling hash of handshake messages. */
814 EVP_MD_CTX *handshake_hash;
815
811 /* this is set whenerver we see a change_cipher_spec message 816 /* this is set whenerver we see a change_cipher_spec message
812 * come in when we are not looking for one */ 817 * come in when we are not looking for one */
813 int change_cipher_spec; 818 int change_cipher_spec;
@@ -1099,6 +1104,7 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
1099 const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size); 1104 const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size);
1100int ssl_cipher_get_evp_aead(const SSL_SESSION *s, const EVP_AEAD **aead); 1105int ssl_cipher_get_evp_aead(const SSL_SESSION *s, const EVP_AEAD **aead);
1101int ssl_get_handshake_digest(int i, long *mask, const EVP_MD **md); 1106int ssl_get_handshake_digest(int i, long *mask, const EVP_MD **md);
1107int ssl_get_handshake_evp_md(SSL *s, const EVP_MD **md);
1102 1108
1103int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk); 1109int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk);
1104int ssl_undefined_function(SSL *s); 1110int ssl_undefined_function(SSL *s);
@@ -1272,6 +1278,12 @@ int dtls1_enc(SSL *s, int snd);
1272int ssl_init_wbio_buffer(SSL *s, int push); 1278int ssl_init_wbio_buffer(SSL *s, int push);
1273void ssl_free_wbio_buffer(SSL *s); 1279void ssl_free_wbio_buffer(SSL *s);
1274 1280
1281int tls1_handshake_hash_init(SSL *s);
1282int tls1_handshake_hash_update(SSL *s, const unsigned char *buf, size_t len);
1283int tls1_handshake_hash_value(SSL *s, const unsigned char *out, size_t len,
1284 size_t *outlen);
1285void tls1_handshake_hash_free(SSL *s);
1286
1275int tls1_init_finished_mac(SSL *s); 1287int tls1_init_finished_mac(SSL *s);
1276int tls1_finish_mac(SSL *s, const unsigned char *buf, int len); 1288int tls1_finish_mac(SSL *s, const unsigned char *buf, int len);
1277void tls1_free_digest_list(SSL *s); 1289void tls1_free_digest_list(SSL *s);
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c
index 09ea657174..a48cf246da 100644
--- a/src/lib/libssl/ssl_srvr.c
+++ b/src/lib/libssl/ssl_srvr.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_srvr.c,v 1.9 2017/03/05 14:24:12 jsing Exp $ */ 1/* $OpenBSD: ssl_srvr.c,v 1.10 2017/03/05 14:39:53 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -1045,6 +1045,9 @@ ssl3_get_client_hello(SSL *s)
1045 S3I(s)->tmp.new_cipher = s->session->cipher; 1045 S3I(s)->tmp.new_cipher = s->session->cipher;
1046 } 1046 }
1047 1047
1048 if (!tls1_handshake_hash_init(s))
1049 goto err;
1050
1048 alg_k = S3I(s)->tmp.new_cipher->algorithm_mkey; 1051 alg_k = S3I(s)->tmp.new_cipher->algorithm_mkey;
1049 if (!(SSL_USE_SIGALGS(s) || (alg_k & SSL_kGOST)) || 1052 if (!(SSL_USE_SIGALGS(s) || (alg_k & SSL_kGOST)) ||
1050 !(s->verify_mode & SSL_VERIFY_PEER)) { 1053 !(s->verify_mode & SSL_VERIFY_PEER)) {
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c
index 85d28298bf..62578beeea 100644
--- a/src/lib/libssl/t1_enc.c
+++ b/src/lib/libssl/t1_enc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: t1_enc.c,v 1.96 2017/02/07 02:08:38 beck Exp $ */ 1/* $OpenBSD: t1_enc.c,v 1.97 2017/03/05 14:39:53 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -135,6 +135,7 @@
135 * OTHERWISE. 135 * OTHERWISE.
136 */ 136 */
137 137
138#include <limits.h>
138#include <stdio.h> 139#include <stdio.h>
139 140
140#include "ssl_locl.h" 141#include "ssl_locl.h"
@@ -193,6 +194,12 @@ tls1_finish_mac(SSL *s, const unsigned char *buf, int len)
193{ 194{
194 int i; 195 int i;
195 196
197 if (len < 0)
198 return 0;
199
200 if (!tls1_handshake_hash_update(s, buf, len))
201 return 0;
202
196 if (S3I(s)->handshake_buffer && 203 if (S3I(s)->handshake_buffer &&
197 !(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) { 204 !(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) {
198 BIO_write(S3I(s)->handshake_buffer, (void *)buf, len); 205 BIO_write(S3I(s)->handshake_buffer, (void *)buf, len);
@@ -1121,52 +1128,23 @@ tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out)
1121int 1128int
1122tls1_final_finish_mac(SSL *s, const char *str, int slen, unsigned char *out) 1129tls1_final_finish_mac(SSL *s, const char *str, int slen, unsigned char *out)
1123{ 1130{
1124 unsigned int i; 1131 unsigned char buf1[EVP_MAX_MD_SIZE];
1125 EVP_MD_CTX ctx; 1132 unsigned char buf2[12];
1126 unsigned char buf[2*EVP_MAX_MD_SIZE]; 1133 size_t hlen;
1127 unsigned char *q, buf2[12];
1128 int idx;
1129 long mask;
1130 int err = 0;
1131 const EVP_MD *md;
1132
1133 q = buf;
1134 1134
1135 if (S3I(s)->handshake_buffer) 1135 if (!tls1_handshake_hash_value(s, buf1, sizeof(buf1), &hlen))
1136 if (!tls1_digest_cached_records(s)) 1136 return 0;
1137 return 0;
1138
1139 EVP_MD_CTX_init(&ctx);
1140 1137
1141 for (idx = 0; ssl_get_handshake_digest(idx, &mask, &md); idx++) { 1138 if (hlen > INT_MAX)
1142 if (ssl_get_algorithm2(s) & mask) { 1139 return 0;
1143 int hashsize = EVP_MD_size(md);
1144 EVP_MD_CTX *hdgst = S3I(s)->handshake_dgst[idx];
1145 if (!hdgst || hashsize < 0 ||
1146 hashsize > (int)(sizeof buf - (size_t)(q - buf))) {
1147 /* internal error: 'buf' is too small for this cipersuite! */
1148 err = 1;
1149 } else {
1150 if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
1151 !EVP_DigestFinal_ex(&ctx, q, &i) ||
1152 (i != (unsigned int)hashsize))
1153 err = 1;
1154 q += hashsize;
1155 }
1156 }
1157 }
1158 1140
1159 if (!tls1_PRF(ssl_get_algorithm2(s), str, slen, buf, (int)(q - buf), 1141 if (!tls1_PRF(ssl_get_algorithm2(s), str, slen, buf1, hlen,
1160 NULL, 0, NULL, 0, NULL, 0, 1142 NULL, 0, NULL, 0, NULL, 0,
1161 s->session->master_key, s->session->master_key_length, 1143 s->session->master_key, s->session->master_key_length,
1162 out, buf2, sizeof buf2)) 1144 out, buf2, sizeof(buf2)))
1163 err = 1;
1164 EVP_MD_CTX_cleanup(&ctx);
1165
1166 if (err)
1167 return 0; 1145 return 0;
1168 else 1146
1169 return sizeof buf2; 1147 return sizeof(buf2);
1170} 1148}
1171 1149
1172int 1150int
diff --git a/src/lib/libssl/t1_hash.c b/src/lib/libssl/t1_hash.c
new file mode 100644
index 0000000000..94410e4127
--- /dev/null
+++ b/src/lib/libssl/t1_hash.c
@@ -0,0 +1,110 @@
1/*
2 * Copyright (c) 2017 Joel Sing <jsing@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "ssl_locl.h"
18
19#include <openssl/ssl.h>
20
21int
22tls1_handshake_hash_init(SSL *s)
23{
24 const EVP_MD *md;
25 long dlen;
26 void *data;
27
28 tls1_handshake_hash_free(s);
29
30 if (!ssl_get_handshake_evp_md(s, &md)) {
31 SSLerrorx(ERR_R_INTERNAL_ERROR);
32 goto err;
33 }
34
35 if ((S3I(s)->handshake_hash = EVP_MD_CTX_create()) == NULL) {
36 SSLerror(s, ERR_R_MALLOC_FAILURE);
37 goto err;
38 }
39 if (!EVP_DigestInit_ex(S3I(s)->handshake_hash, md, NULL)) {
40 SSLerror(s, ERR_R_EVP_LIB);
41 goto err;
42 }
43
44 dlen = BIO_get_mem_data(S3I(s)->handshake_buffer, &data);
45 if (dlen <= 0) {
46 SSLerror(s, SSL_R_BAD_HANDSHAKE_LENGTH);
47 goto err;
48 }
49 if (!tls1_handshake_hash_update(s, data, dlen)) {
50 SSLerror(s, ERR_R_EVP_LIB);
51 goto err;
52 }
53
54 return 1;
55
56 err:
57 tls1_handshake_hash_free(s);
58
59 return 0;
60}
61
62int
63tls1_handshake_hash_update(SSL *s, const unsigned char *buf, size_t len)
64{
65 if (S3I(s)->handshake_hash == NULL)
66 return 1;
67
68 return EVP_DigestUpdate(S3I(s)->handshake_hash, buf, len);
69}
70
71int
72tls1_handshake_hash_value(SSL *s, const unsigned char *out, size_t len,
73 size_t *outlen)
74{
75 EVP_MD_CTX *mdctx = NULL;
76 unsigned int mdlen;
77 int ret = 0;
78
79 if (EVP_MD_CTX_size(S3I(s)->handshake_hash) > len)
80 goto err;
81
82 if ((mdctx = EVP_MD_CTX_create()) == NULL) {
83 SSLerror(s, ERR_R_MALLOC_FAILURE);
84 goto err;
85 }
86 if (!EVP_MD_CTX_copy_ex(mdctx, S3I(s)->handshake_hash)) {
87 SSLerror(s, ERR_R_EVP_LIB);
88 goto err;
89 }
90 if (!EVP_DigestFinal_ex(mdctx, (unsigned char *)out, &mdlen)) {
91 SSLerror(s, ERR_R_EVP_LIB);
92 goto err;
93 }
94 if (outlen != NULL)
95 *outlen = mdlen;
96
97 ret = 1;
98
99 err:
100 EVP_MD_CTX_destroy(mdctx);
101
102 return (ret);
103}
104
105void
106tls1_handshake_hash_free(SSL *s)
107{
108 EVP_MD_CTX_destroy(S3I(s)->handshake_hash);
109 S3I(s)->handshake_hash = NULL;
110}