Resolve a TODO in ssl3_dispatch_alert
[openssl.git] / ssl / s3_lib.c
index 1091b8831d1da7e81ee23f48346d662ce3cbead2..e7078efa6c5aaaa74a6185b72244dbcf3c0b4c19 100644 (file)
@@ -3255,9 +3255,9 @@ void ssl_sort_cipher_list(void)
     qsort(ssl3_scsvs, SSL3_NUM_SCSVS, sizeof(ssl3_scsvs[0]), cipher_compare);
 }
 
-static int ssl_undefined_function_1(SSL *ssl, unsigned char *r, size_t s,
-                                    const char * t, size_t u,
-                                    const unsigned char * v, size_t w, int x)
+static int sslcon_undefined_function_1(SSL_CONNECTION *sc, unsigned char *r,
+                                       size_t s, const char *t, size_t u,
+                                       const unsigned char *v, size_t w, int x)
 {
     (void)r;
     (void)s;
@@ -3266,12 +3266,10 @@ static int ssl_undefined_function_1(SSL *ssl, unsigned char *r, size_t s,
     (void)v;
     (void)w;
     (void)x;
-    return ssl_undefined_function(ssl);
+    return ssl_undefined_function(SSL_CONNECTION_GET_SSL(sc));
 }
 
 const SSL3_ENC_METHOD SSLv3_enc_data = {
-    ssl3_enc,
-    n_ssl3_mac,
     ssl3_setup_key_block,
     ssl3_generate_master_secret,
     ssl3_change_cipher_state,
@@ -3279,20 +3277,20 @@ const SSL3_ENC_METHOD SSLv3_enc_data = {
     SSL3_MD_CLIENT_FINISHED_CONST, 4,
     SSL3_MD_SERVER_FINISHED_CONST, 4,
     ssl3_alert_code,
-    ssl_undefined_function_1,
+    sslcon_undefined_function_1,
     0,
     ssl3_set_handshake_header,
     tls_close_construct_packet,
     ssl3_handshake_write
 };
 
-long ssl3_default_timeout(void)
+OSSL_TIME ssl3_default_timeout(void)
 {
     /*
      * 2 hours, the 24 hours mentioned in the SSLv3 spec is way too long for
      * http, the cache would over fill
      */
-    return (60 * 60 * 2);
+    return ossl_seconds2time(60 * 60 * 2);
 }
 
 int ssl3_num_ciphers(void)
@@ -3308,7 +3306,7 @@ const SSL_CIPHER *ssl3_get_cipher(unsigned int u)
         return NULL;
 }
 
-int ssl3_set_handshake_header(SSL *s, WPACKET *pkt, int htype)
+int ssl3_set_handshake_header(SSL_CONNECTION *s, WPACKET *pkt, int htype)
 {
     /* No header in the event of a CCS */
     if (htype == SSL3_MT_CHANGE_CIPHER_SPEC)
@@ -3322,7 +3320,7 @@ int ssl3_set_handshake_header(SSL *s, WPACKET *pkt, int htype)
     return 1;
 }
 
-int ssl3_handshake_write(SSL *s)
+int ssl3_handshake_write(SSL_CONNECTION *s)
 {
     return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
 }
@@ -3330,7 +3328,12 @@ int ssl3_handshake_write(SSL *s)
 int ssl3_new(SSL *s)
 {
 #ifndef OPENSSL_NO_SRP
-    if (!ssl_srp_ctx_init_intern(s))
+    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+
+    if (sc == NULL)
+        return 0;
+
+    if (!ssl_srp_ctx_init_intern(sc))
         return 0;
 #endif
 
@@ -3342,65 +3345,72 @@ int ssl3_new(SSL *s)
 
 void ssl3_free(SSL *s)
 {
-    if (s == NULL)
+    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+
+    if (sc == NULL)
         return;
 
-    ssl3_cleanup_key_block(s);
+    ssl3_cleanup_key_block(sc);
 
-    EVP_PKEY_free(s->s3.peer_tmp);
-    s->s3.peer_tmp = NULL;
-    EVP_PKEY_free(s->s3.tmp.pkey);
-    s->s3.tmp.pkey = NULL;
+    EVP_PKEY_free(sc->s3.peer_tmp);
+    sc->s3.peer_tmp = NULL;
+    EVP_PKEY_free(sc->s3.tmp.pkey);
+    sc->s3.tmp.pkey = NULL;
 
-    ssl_evp_cipher_free(s->s3.tmp.new_sym_enc);
-    ssl_evp_md_free(s->s3.tmp.new_hash);
+    ssl_evp_cipher_free(sc->s3.tmp.new_sym_enc);
+    ssl_evp_md_free(sc->s3.tmp.new_hash);
 
-    OPENSSL_free(s->s3.tmp.ctype);
-    sk_X509_NAME_pop_free(s->s3.tmp.peer_ca_names, X509_NAME_free);
-    OPENSSL_free(s->s3.tmp.ciphers_raw);
-    OPENSSL_clear_free(s->s3.tmp.pms, s->s3.tmp.pmslen);
-    OPENSSL_free(s->s3.tmp.peer_sigalgs);
-    OPENSSL_free(s->s3.tmp.peer_cert_sigalgs);
-    ssl3_free_digest_list(s);
-    OPENSSL_free(s->s3.alpn_selected);
-    OPENSSL_free(s->s3.alpn_proposed);
+    OPENSSL_free(sc->s3.tmp.ctype);
+    sk_X509_NAME_pop_free(sc->s3.tmp.peer_ca_names, X509_NAME_free);
+    OPENSSL_free(sc->s3.tmp.ciphers_raw);
+    OPENSSL_clear_free(sc->s3.tmp.pms, sc->s3.tmp.pmslen);
+    OPENSSL_free(sc->s3.tmp.peer_sigalgs);
+    OPENSSL_free(sc->s3.tmp.peer_cert_sigalgs);
+    ssl3_free_digest_list(sc);
+    OPENSSL_free(sc->s3.alpn_selected);
+    OPENSSL_free(sc->s3.alpn_proposed);
 
 #ifndef OPENSSL_NO_SRP
-    ssl_srp_ctx_free_intern(s);
+    ssl_srp_ctx_free_intern(sc);
 #endif
-    memset(&s->s3, 0, sizeof(s->s3));
+    memset(&sc->s3, 0, sizeof(sc->s3));
 }
 
 int ssl3_clear(SSL *s)
 {
-    ssl3_cleanup_key_block(s);
-    OPENSSL_free(s->s3.tmp.ctype);
-    sk_X509_NAME_pop_free(s->s3.tmp.peer_ca_names, X509_NAME_free);
-    OPENSSL_free(s->s3.tmp.ciphers_raw);
-    OPENSSL_clear_free(s->s3.tmp.pms, s->s3.tmp.pmslen);
-    OPENSSL_free(s->s3.tmp.peer_sigalgs);
-    OPENSSL_free(s->s3.tmp.peer_cert_sigalgs);
+    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+
+    if (sc == NULL)
+        return 0;
+
+    ssl3_cleanup_key_block(sc);
+    OPENSSL_free(sc->s3.tmp.ctype);
+    sk_X509_NAME_pop_free(sc->s3.tmp.peer_ca_names, X509_NAME_free);
+    OPENSSL_free(sc->s3.tmp.ciphers_raw);
+    OPENSSL_clear_free(sc->s3.tmp.pms, sc->s3.tmp.pmslen);
+    OPENSSL_free(sc->s3.tmp.peer_sigalgs);
+    OPENSSL_free(sc->s3.tmp.peer_cert_sigalgs);
 
-    EVP_PKEY_free(s->s3.tmp.pkey);
-    EVP_PKEY_free(s->s3.peer_tmp);
+    EVP_PKEY_free(sc->s3.tmp.pkey);
+    EVP_PKEY_free(sc->s3.peer_tmp);
 
-    ssl3_free_digest_list(s);
+    ssl3_free_digest_list(sc);
 
-    OPENSSL_free(s->s3.alpn_selected);
-    OPENSSL_free(s->s3.alpn_proposed);
+    OPENSSL_free(sc->s3.alpn_selected);
+    OPENSSL_free(sc->s3.alpn_proposed);
 
     /* NULL/zero-out everything in the s3 struct */
-    memset(&s->s3, 0, sizeof(s->s3));
+    memset(&sc->s3, 0, sizeof(sc->s3));
 
-    if (!ssl_free_wbio_buffer(s))
+    if (!ssl_free_wbio_buffer(sc))
         return 0;
 
-    s->version = SSL3_VERSION;
+    sc->version = SSL3_VERSION;
 
 #if !defined(OPENSSL_NO_NEXTPROTONEG)
-    OPENSSL_free(s->ext.npn);
-    s->ext.npn = NULL;
-    s->ext.npn_len = 0;
+    OPENSSL_free(sc->ext.npn);
+    sc->ext.npn = NULL;
+    sc->ext.npn_len = 0;
 #endif
 
     return 1;
@@ -3409,7 +3419,12 @@ int ssl3_clear(SSL *s)
 #ifndef OPENSSL_NO_SRP
 static char *srp_password_from_info_cb(SSL *s, void *arg)
 {
-    return OPENSSL_strdup(s->srp_ctx.info);
+    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+
+    if (sc == NULL)
+        return NULL;
+
+    return OPENSSL_strdup(sc->srp_ctx.info);
 }
 #endif
 
@@ -3418,22 +3433,26 @@ static int ssl3_set_req_cert_type(CERT *c, const unsigned char *p, size_t len);
 long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
 {
     int ret = 0;
+    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+
+    if (sc == NULL)
+        return ret;
 
     switch (cmd) {
     case SSL_CTRL_GET_CLIENT_CERT_REQUEST:
         break;
     case SSL_CTRL_GET_NUM_RENEGOTIATIONS:
-        ret = s->s3.num_renegotiations;
+        ret = sc->s3.num_renegotiations;
         break;
     case SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS:
-        ret = s->s3.num_renegotiations;
-        s->s3.num_renegotiations = 0;
+        ret = sc->s3.num_renegotiations;
+        sc->s3.num_renegotiations = 0;
         break;
     case SSL_CTRL_GET_TOTAL_RENEGOTIATIONS:
-        ret = s->s3.total_renegotiations;
+        ret = sc->s3.total_renegotiations;
         break;
     case SSL_CTRL_GET_FLAGS:
-        ret = (int)(s->s3.flags);
+        ret = (int)(sc->s3.flags);
         break;
 #if !defined(OPENSSL_NO_DEPRECATED_3_0)
     case SSL_CTRL_SET_TMP_DH:
@@ -3445,7 +3464,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
             }
             pkdh = ssl_dh_to_pkey(parg);
             if (pkdh == NULL) {
-                ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
+                ERR_raise(ERR_LIB_SSL, ERR_R_DH_LIB);
                 return 0;
             }
             if (!SSL_set0_tmp_dh_pkey(s, pkdh)) {
@@ -3462,7 +3481,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
         }
 #endif
     case SSL_CTRL_SET_DH_AUTO:
-        s->cert->dh_tmp_auto = larg;
+        sc->cert->dh_tmp_auto = larg;
         return 1;
 #if !defined(OPENSSL_NO_DEPRECATED_3_0)
     case SSL_CTRL_SET_TMP_ECDH:
@@ -3471,8 +3490,8 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
                 ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER);
                 return 0;
             }
-            return ssl_set_tmp_ecdh_groups(&s->ext.supportedgroups,
-                                           &s->ext.supportedgroups_len,
+            return ssl_set_tmp_ecdh_groups(&sc->ext.supportedgroups,
+                                           &sc->ext.supportedgroups_len,
                                            parg);
         }
 #endif                          /* !OPENSSL_NO_DEPRECATED_3_0 */
@@ -3488,8 +3507,8 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
         if (larg == TLSEXT_NAMETYPE_host_name) {
             size_t len;
 
-            OPENSSL_free(s->ext.hostname);
-            s->ext.hostname = NULL;
+            OPENSSL_free(sc->ext.hostname);
+            sc->ext.hostname = NULL;
 
             ret = 1;
             if (parg == NULL)
@@ -3499,7 +3518,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
                 ERR_raise(ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_SERVERNAME);
                 return 0;
             }
-            if ((s->ext.hostname = OPENSSL_strdup((char *)parg)) == NULL) {
+            if ((sc->ext.hostname = OPENSSL_strdup((char *)parg)) == NULL) {
                 ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
                 return 0;
             }
@@ -3509,79 +3528,79 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
         }
         break;
     case SSL_CTRL_SET_TLSEXT_DEBUG_ARG:
-        s->ext.debug_arg = parg;
+        sc->ext.debug_arg = parg;
         ret = 1;
         break;
 
     case SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE:
-        ret = s->ext.status_type;
+        ret = sc->ext.status_type;
         break;
 
     case SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE:
-        s->ext.status_type = larg;
+        sc->ext.status_type = larg;
         ret = 1;
         break;
 
     case SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS:
-        *(STACK_OF(X509_EXTENSION) **)parg = s->ext.ocsp.exts;
+        *(STACK_OF(X509_EXTENSION) **)parg = sc->ext.ocsp.exts;
         ret = 1;
         break;
 
     case SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS:
-        s->ext.ocsp.exts = parg;
+        sc->ext.ocsp.exts = parg;
         ret = 1;
         break;
 
     case SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS:
-        *(STACK_OF(OCSP_RESPID) **)parg = s->ext.ocsp.ids;
+        *(STACK_OF(OCSP_RESPID) **)parg = sc->ext.ocsp.ids;
         ret = 1;
         break;
 
     case SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS:
-        s->ext.ocsp.ids = parg;
+        sc->ext.ocsp.ids = parg;
         ret = 1;
         break;
 
     case SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP:
-        *(unsigned char **)parg = s->ext.ocsp.resp;
-        if (s->ext.ocsp.resp_len == 0
-                || s->ext.ocsp.resp_len > LONG_MAX)
+        *(unsigned char **)parg = sc->ext.ocsp.resp;
+        if (sc->ext.ocsp.resp_len == 0
+                || sc->ext.ocsp.resp_len > LONG_MAX)
             return -1;
-        return (long)s->ext.ocsp.resp_len;
+        return (long)sc->ext.ocsp.resp_len;
 
     case SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP:
-        OPENSSL_free(s->ext.ocsp.resp);
-        s->ext.ocsp.resp = parg;
-        s->ext.ocsp.resp_len = larg;
+        OPENSSL_free(sc->ext.ocsp.resp);
+        sc->ext.ocsp.resp = parg;
+        sc->ext.ocsp.resp_len = larg;
         ret = 1;
         break;
 
     case SSL_CTRL_CHAIN:
         if (larg)
-            return ssl_cert_set1_chain(s, NULL, (STACK_OF(X509) *)parg);
+            return ssl_cert_set1_chain(sc, NULL, (STACK_OF(X509) *)parg);
         else
-            return ssl_cert_set0_chain(s, NULL, (STACK_OF(X509) *)parg);
+            return ssl_cert_set0_chain(sc, NULL, (STACK_OF(X509) *)parg);
 
     case SSL_CTRL_CHAIN_CERT:
         if (larg)
-            return ssl_cert_add1_chain_cert(s, NULL, (X509 *)parg);
+            return ssl_cert_add1_chain_cert(sc, NULL, (X509 *)parg);
         else
-            return ssl_cert_add0_chain_cert(s, NULL, (X509 *)parg);
+            return ssl_cert_add0_chain_cert(sc, NULL, (X509 *)parg);
 
     case SSL_CTRL_GET_CHAIN_CERTS:
-        *(STACK_OF(X509) **)parg = s->cert->key->chain;
+        *(STACK_OF(X509) **)parg = sc->cert->key->chain;
         ret = 1;
         break;
 
     case SSL_CTRL_SELECT_CURRENT_CERT:
-        return ssl_cert_select_current(s->cert, (X509 *)parg);
+        return ssl_cert_select_current(sc->cert, (X509 *)parg);
 
     case SSL_CTRL_SET_CURRENT_CERT:
         if (larg == SSL_CERT_SET_SERVER) {
             const SSL_CIPHER *cipher;
-            if (!s->server)
+            if (!sc->server)
                 return 0;
-            cipher = s->s3.tmp.new_cipher;
+            cipher = sc->s3.tmp.new_cipher;
             if (cipher == NULL)
                 return 0;
             /*
@@ -3590,32 +3609,29 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
              */
             if (cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP))
                 return 2;
-            if (s->s3.tmp.cert == NULL)
+            if (sc->s3.tmp.cert == NULL)
                 return 0;
-            s->cert->key = s->s3.tmp.cert;
+            sc->cert->key = sc->s3.tmp.cert;
             return 1;
         }
-        return ssl_cert_set_current(s->cert, larg);
+        return ssl_cert_set_current(sc->cert, larg);
 
     case SSL_CTRL_GET_GROUPS:
         {
             uint16_t *clist;
             size_t clistlen;
 
-            if (!s->session)
+            if (!sc->session)
                 return 0;
-            clist = s->ext.peer_supportedgroups;
-            clistlen = s->ext.peer_supportedgroups_len;
+            clist = sc->ext.peer_supportedgroups;
+            clistlen = sc->ext.peer_supportedgroups_len;
             if (parg) {
                 size_t i;
                 int *cptr = parg;
 
                 for (i = 0; i < clistlen; i++) {
-                    uint16_t cid = SSL_IS_TLS13(s)
-                                   ? ssl_group_id_tls13_to_internal(clist[i])
-                                   : clist[i];
                     const TLS_GROUP_INFO *cinf
-                        = tls1_group_id_lookup(s->ctx, cid);
+                        = tls1_group_id_lookup(s->ctx, clist[i]);
 
                     if (cinf != NULL)
                         cptr[i] = tls1_group_id2nid(cinf->group_id, 1);
@@ -3627,16 +3643,16 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
         }
 
     case SSL_CTRL_SET_GROUPS:
-        return tls1_set_groups(&s->ext.supportedgroups,
-                               &s->ext.supportedgroups_len, parg, larg);
+        return tls1_set_groups(&sc->ext.supportedgroups,
+                               &sc->ext.supportedgroups_len, parg, larg);
 
     case SSL_CTRL_SET_GROUPS_LIST:
-        return tls1_set_groups_list(s->ctx, &s->ext.supportedgroups,
-                                    &s->ext.supportedgroups_len, parg);
+        return tls1_set_groups_list(s->ctx, &sc->ext.supportedgroups,
+                                    &sc->ext.supportedgroups_len, parg);
 
     case SSL_CTRL_GET_SHARED_GROUP:
         {
-            uint16_t id = tls1_shared_group(s, larg);
+            uint16_t id = tls1_shared_group(sc, larg);
 
             if (larg != -1)
                 return tls1_group_id2nid(id, 1);
@@ -3646,82 +3662,82 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
         {
             unsigned int id;
 
-            if (SSL_IS_TLS13(s) && s->s3.did_kex)
-                id = s->s3.group_id;
+            if (SSL_CONNECTION_IS_TLS13(sc) && sc->s3.did_kex)
+                id = sc->s3.group_id;
             else
-                id = s->session->kex_group;
+                id = sc->session->kex_group;
             ret = tls1_group_id2nid(id, 1);
             break;
         }
     case SSL_CTRL_SET_SIGALGS:
-        return tls1_set_sigalgs(s->cert, parg, larg, 0);
+        return tls1_set_sigalgs(sc->cert, parg, larg, 0);
 
     case SSL_CTRL_SET_SIGALGS_LIST:
-        return tls1_set_sigalgs_list(s->cert, parg, 0);
+        return tls1_set_sigalgs_list(sc->cert, parg, 0);
 
     case SSL_CTRL_SET_CLIENT_SIGALGS:
-        return tls1_set_sigalgs(s->cert, parg, larg, 1);
+        return tls1_set_sigalgs(sc->cert, parg, larg, 1);
 
     case SSL_CTRL_SET_CLIENT_SIGALGS_LIST:
-        return tls1_set_sigalgs_list(s->cert, parg, 1);
+        return tls1_set_sigalgs_list(sc->cert, parg, 1);
 
     case SSL_CTRL_GET_CLIENT_CERT_TYPES:
         {
             const unsigned char **pctype = parg;
-            if (s->server || !s->s3.tmp.cert_req)
+            if (sc->server || !sc->s3.tmp.cert_req)
                 return 0;
             if (pctype)
-                *pctype = s->s3.tmp.ctype;
-            return s->s3.tmp.ctype_len;
+                *pctype = sc->s3.tmp.ctype;
+            return sc->s3.tmp.ctype_len;
         }
 
     case SSL_CTRL_SET_CLIENT_CERT_TYPES:
-        if (!s->server)
+        if (!sc->server)
             return 0;
-        return ssl3_set_req_cert_type(s->cert, parg, larg);
+        return ssl3_set_req_cert_type(sc->cert, parg, larg);
 
     case SSL_CTRL_BUILD_CERT_CHAIN:
-        return ssl_build_cert_chain(s, NULL, larg);
+        return ssl_build_cert_chain(sc, NULL, larg);
 
     case SSL_CTRL_SET_VERIFY_CERT_STORE:
-        return ssl_cert_set_cert_store(s->cert, parg, 0, larg);
+        return ssl_cert_set_cert_store(sc->cert, parg, 0, larg);
 
     case SSL_CTRL_SET_CHAIN_CERT_STORE:
-        return ssl_cert_set_cert_store(s->cert, parg, 1, larg);
+        return ssl_cert_set_cert_store(sc->cert, parg, 1, larg);
 
     case SSL_CTRL_GET_VERIFY_CERT_STORE:
-        return ssl_cert_get_cert_store(s->cert, parg, 0);
+        return ssl_cert_get_cert_store(sc->cert, parg, 0);
 
     case SSL_CTRL_GET_CHAIN_CERT_STORE:
-        return ssl_cert_get_cert_store(s->cert, parg, 1);
+        return ssl_cert_get_cert_store(sc->cert, parg, 1);
 
     case SSL_CTRL_GET_PEER_SIGNATURE_NID:
-        if (s->s3.tmp.peer_sigalg == NULL)
+        if (sc->s3.tmp.peer_sigalg == NULL)
             return 0;
-        *(int *)parg = s->s3.tmp.peer_sigalg->hash;
+        *(int *)parg = sc->s3.tmp.peer_sigalg->hash;
         return 1;
 
     case SSL_CTRL_GET_SIGNATURE_NID:
-        if (s->s3.tmp.sigalg == NULL)
+        if (sc->s3.tmp.sigalg == NULL)
             return 0;
-        *(int *)parg = s->s3.tmp.sigalg->hash;
+        *(int *)parg = sc->s3.tmp.sigalg->hash;
         return 1;
 
     case SSL_CTRL_GET_PEER_TMP_KEY:
-        if (s->session == NULL || s->s3.peer_tmp == NULL) {
+        if (sc->session == NULL || sc->s3.peer_tmp == NULL) {
             return 0;
         } else {
-            EVP_PKEY_up_ref(s->s3.peer_tmp);
-            *(EVP_PKEY **)parg = s->s3.peer_tmp;
+            EVP_PKEY_up_ref(sc->s3.peer_tmp);
+            *(EVP_PKEY **)parg = sc->s3.peer_tmp;
             return 1;
         }
 
     case SSL_CTRL_GET_TMP_KEY:
-        if (s->session == NULL || s->s3.tmp.pkey == NULL) {
+        if (sc->session == NULL || sc->s3.tmp.pkey == NULL) {
             return 0;
         } else {
-            EVP_PKEY_up_ref(s->s3.tmp.pkey);
-            *(EVP_PKEY **)parg = s->s3.tmp.pkey;
+            EVP_PKEY_up_ref(sc->s3.tmp.pkey);
+            *(EVP_PKEY **)parg = sc->s3.tmp.pkey;
             return 1;
         }
 
@@ -3729,18 +3745,18 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
         {
             const unsigned char **pformat = parg;
 
-            if (s->ext.peer_ecpointformats == NULL)
+            if (sc->ext.peer_ecpointformats == NULL)
                 return 0;
-            *pformat = s->ext.peer_ecpointformats;
-            return (int)s->ext.peer_ecpointformats_len;
+            *pformat = sc->ext.peer_ecpointformats;
+            return (int)sc->ext.peer_ecpointformats_len;
         }
 
     case SSL_CTRL_GET_IANA_GROUPS:
         {
             if (parg != NULL) {
-                *(uint16_t **)parg = (uint16_t *)s->ext.peer_supportedgroups;
+                *(uint16_t **)parg = (uint16_t *)sc->ext.peer_supportedgroups;
             }
-            return (int)s->ext.peer_supportedgroups_len;
+            return (int)sc->ext.peer_supportedgroups_len;
         }
 
     default:
@@ -3752,22 +3768,26 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
 long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void))
 {
     int ret = 0;
+    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+
+    if (sc == NULL)
+        return ret;
 
     switch (cmd) {
 #if !defined(OPENSSL_NO_DEPRECATED_3_0)
     case SSL_CTRL_SET_TMP_DH_CB:
-        s->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp;
+        sc->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp;
         ret = 1;
         break;
 #endif
     case SSL_CTRL_SET_TLSEXT_DEBUG_CB:
-        s->ext.debug_cb = (void (*)(SSL *, int, int,
-                                    const unsigned char *, int, void *))fp;
+        sc->ext.debug_cb = (void (*)(SSL *, int, int,
+                                     const unsigned char *, int, void *))fp;
         ret = 1;
         break;
 
     case SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB:
-        s->not_resumable_session_cb = (int (*)(SSL *, int))fp;
+        sc->not_resumable_session_cb = (int (*)(SSL *, int))fp;
         ret = 1;
         break;
     default:
@@ -3789,7 +3809,7 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
             }
             pkdh = ssl_dh_to_pkey(parg);
             if (pkdh == NULL) {
-                ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
+                ERR_raise(ERR_LIB_SSL, ERR_R_DH_LIB);
                 return 0;
             }
             if (!SSL_CTX_set0_tmp_dh_pkey(ctx, pkdh)) {
@@ -3958,12 +3978,12 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
     case SSL_CTRL_EXTRA_CHAIN_CERT:
         if (ctx->extra_certs == NULL) {
             if ((ctx->extra_certs = sk_X509_new_null()) == NULL) {
-                ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
+                ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
                 return 0;
             }
         }
         if (!sk_X509_push(ctx->extra_certs, (X509 *)parg)) {
-            ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
+            ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
             return 0;
         }
         break;
@@ -4029,9 +4049,9 @@ long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void))
 # ifndef OPENSSL_NO_DEPRECATED_3_0
     case SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB:
         ctx->ext.ticket_key_cb = (int (*)(SSL *, unsigned char *,
-                                             unsigned char *,
-                                             EVP_CIPHER_CTX *,
-                                             HMAC_CTX *, int))fp;
+                                          unsigned char *,
+                                          EVP_CIPHER_CTX *,
+                                          HMAC_CTX *, int))fp;
         break;
 #endif
 
@@ -4138,7 +4158,7 @@ int ssl3_put_cipher_by_char(const SSL_CIPHER *c, WPACKET *pkt, size_t *len)
  *
  * Returns the selected cipher or NULL when no common ciphers.
  */
-const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
+const SSL_CIPHER *ssl3_choose_cipher(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *clnt,
                                      STACK_OF(SSL_CIPHER) *srvr)
 {
     const SSL_CIPHER *c, *ret = NULL;
@@ -4222,7 +4242,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
         allow = srvr;
     }
 
-    if (SSL_IS_TLS13(s)) {
+    if (SSL_CONNECTION_IS_TLS13(s)) {
 #ifndef OPENSSL_NO_PSK
         int j;
 
@@ -4250,10 +4270,10 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
         c = sk_SSL_CIPHER_value(prio, i);
 
         /* Skip ciphers not supported by the protocol version */
-        if (!SSL_IS_DTLS(s) &&
+        if (!SSL_CONNECTION_IS_DTLS(s) &&
             ((s->version < c->min_tls) || (s->version > c->max_tls)))
             continue;
-        if (SSL_IS_DTLS(s) &&
+        if (SSL_CONNECTION_IS_DTLS(s) &&
             (DTLS_VERSION_LT(s->version, c->min_dtls) ||
              DTLS_VERSION_GT(s->version, c->max_dtls)))
             continue;
@@ -4262,7 +4282,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
          * Since TLS 1.3 ciphersuites can be used with any auth or
          * key exchange scheme skip tests.
          */
-        if (!SSL_IS_TLS13(s)) {
+        if (!SSL_CONNECTION_IS_TLS13(s)) {
             mask_k = s->s3.tmp.mask_k;
             mask_a = s->s3.tmp.mask_a;
 #ifndef OPENSSL_NO_SRP
@@ -4312,9 +4332,11 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
 
             if (prefer_sha256) {
                 const SSL_CIPHER *tmp = sk_SSL_CIPHER_value(allow, ii);
+                const EVP_MD *md = ssl_md(SSL_CONNECTION_GET_CTX(s),
+                                          tmp->algorithm2);
 
-                if (EVP_MD_is_a(ssl_md(s->ctx, tmp->algorithm2),
-                                       OSSL_DIGEST_NAME_SHA2_256)) {
+                if (md != NULL
+                        && EVP_MD_is_a(md, OSSL_DIGEST_NAME_SHA2_256)) {
                     ret = tmp;
                     break;
                 }
@@ -4332,7 +4354,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
     return ret;
 }
 
-int ssl3_get_req_cert_type(SSL *s, WPACKET *pkt)
+int ssl3_get_req_cert_type(SSL_CONNECTION *s, WPACKET *pkt)
 {
     uint32_t alg_k, alg_a = 0;
 
@@ -4402,26 +4424,30 @@ static int ssl3_set_req_cert_type(CERT *c, const unsigned char *p, size_t len)
 int ssl3_shutdown(SSL *s)
 {
     int ret;
+    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
+
+    if (sc == NULL)
+        return 0;
 
     /*
      * Don't do anything much if we have not done the handshake or we don't
      * want to send messages :-)
      */
-    if (s->quiet_shutdown || SSL_in_before(s)) {
-        s->shutdown = (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
+    if (sc->quiet_shutdown || SSL_in_before(s)) {
+        sc->shutdown = (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
         return 1;
     }
 
-    if (!(s->shutdown & SSL_SENT_SHUTDOWN)) {
-        s->shutdown |= SSL_SENT_SHUTDOWN;
-        ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY);
+    if (!(sc->shutdown & SSL_SENT_SHUTDOWN)) {
+        sc->shutdown |= SSL_SENT_SHUTDOWN;
+        ssl3_send_alert(sc, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY);
         /*
          * our shutdown alert has been sent now, and if it still needs to be
-         * written, s->s3.alert_dispatch will be true
+         * written, s->s3.alert_dispatch will be > 0
          */
-        if (s->s3.alert_dispatch)
+        if (sc->s3.alert_dispatch > 0)
             return -1;        /* return WANT_WRITE */
-    } else if (s->s3.alert_dispatch) {
+    } else if (sc->s3.alert_dispatch > 0) {
         /* resend it if not sent */
         ret = s->method->ssl_dispatch_alert(s);
         if (ret == -1) {
@@ -4432,19 +4458,19 @@ int ssl3_shutdown(SSL *s)
              */
             return ret;
         }
-    } else if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) {
+    } else if (!(sc->shutdown & SSL_RECEIVED_SHUTDOWN)) {
         size_t readbytes;
         /*
          * If we are waiting for a close from our peer, we are closed
          */
         s->method->ssl_read_bytes(s, 0, NULL, NULL, 0, 0, &readbytes);
-        if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) {
+        if (!(sc->shutdown & SSL_RECEIVED_SHUTDOWN)) {
             return -1;        /* return WANT_READ */
         }
     }
 
-    if ((s->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN)) &&
-        !s->s3.alert_dispatch)
+    if ((sc->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN))
+            && sc->s3.alert_dispatch == SSL_ALERT_DISPATCH_NONE)
         return 1;
     else
         return 0;
@@ -4452,8 +4478,13 @@ int ssl3_shutdown(SSL *s)
 
 int ssl3_write(SSL *s, const void *buf, size_t len, size_t *written)
 {
+    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
+
+    if (sc == NULL)
+        return 0;
+
     clear_sys_error();
-    if (s->s3.renegotiate)
+    if (sc->s3.renegotiate)
         ssl3_renegotiate_check(s, 0);
 
     return s->method->ssl_write_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len,
@@ -4464,15 +4495,19 @@ static int ssl3_read_internal(SSL *s, void *buf, size_t len, int peek,
                               size_t *readbytes)
 {
     int ret;
+    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
+
+    if (sc == NULL)
+        return 0;
 
     clear_sys_error();
-    if (s->s3.renegotiate)
+    if (sc->s3.renegotiate)
         ssl3_renegotiate_check(s, 0);
-    s->s3.in_read_app_data = 1;
+    sc->s3.in_read_app_data = 1;
     ret =
         s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, NULL, buf, len,
                                   peek, readbytes);
-    if ((ret == -1) && (s->s3.in_read_app_data == 2)) {
+    if ((ret == -1) && (sc->s3.in_read_app_data == 2)) {
         /*
          * ssl3_read_bytes decided to call s->handshake_func, which called
          * ssl3_read_bytes to read handshake data. However, ssl3_read_bytes
@@ -4480,13 +4515,13 @@ static int ssl3_read_internal(SSL *s, void *buf, size_t len, int peek,
          * makes sense here; so disable handshake processing and try to read
          * application data again.
          */
-        ossl_statem_set_in_handshake(s, 1);
+        ossl_statem_set_in_handshake(sc, 1);
         ret =
             s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, NULL, buf,
                                       len, peek, readbytes);
-        ossl_statem_set_in_handshake(s, 0);
+        ossl_statem_set_in_handshake(sc, 0);
     } else
-        s->s3.in_read_app_data = 0;
+        sc->s3.in_read_app_data = 0;
 
     return ret;
 }
@@ -4503,10 +4538,15 @@ int ssl3_peek(SSL *s, void *buf, size_t len, size_t *readbytes)
 
 int ssl3_renegotiate(SSL *s)
 {
-    if (s->handshake_func == NULL)
+    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
+
+    if (sc == NULL)
+        return 0;
+
+    if (sc->handshake_func == NULL)
         return 1;
 
-    s->s3.renegotiate = 1;
+    sc->s3.renegotiate = 1;
     return 1;
 }
 
@@ -4521,20 +4561,24 @@ int ssl3_renegotiate(SSL *s)
 int ssl3_renegotiate_check(SSL *s, int initok)
 {
     int ret = 0;
+    SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
+
+    if (sc == NULL)
+        return 0;
 
-    if (s->s3.renegotiate) {
-        if (!RECORD_LAYER_read_pending(&s->rlayer)
-            && !RECORD_LAYER_write_pending(&s->rlayer)
+    if (sc->s3.renegotiate) {
+        if (!RECORD_LAYER_read_pending(&sc->rlayer)
+            && !RECORD_LAYER_write_pending(&sc->rlayer)
             && (initok || !SSL_in_init(s))) {
             /*
              * if we are the server, and we have sent a 'RENEGOTIATE'
              * message, we need to set the state machine into the renegotiate
              * state.
              */
-            ossl_statem_set_renegotiate(s);
-            s->s3.renegotiate = 0;
-            s->s3.num_renegotiations++;
-            s->s3.total_renegotiations++;
+            ossl_statem_set_renegotiate(sc);
+            sc->s3.renegotiate = 0;
+            sc->s3.num_renegotiations++;
+            sc->s3.total_renegotiations++;
             ret = 1;
         }
     }
@@ -4547,13 +4591,15 @@ int ssl3_renegotiate_check(SSL *s, int initok)
  *
  * If PSK and using SHA384 for TLS < 1.2 switch to default.
  */
-long ssl_get_algorithm2(SSL *s)
+long ssl_get_algorithm2(SSL_CONNECTION *s)
 {
     long alg2;
+    SSL *ssl = SSL_CONNECTION_GET_SSL(s);
+
     if (s->s3.tmp.new_cipher == NULL)
         return -1;
     alg2 = s->s3.tmp.new_cipher->algorithm2;
-    if (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF) {
+    if (ssl->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF) {
         if (alg2 == (SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF))
             return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
     } else if (s->s3.tmp.new_cipher->algorithm_mkey & SSL_PSK) {
@@ -4567,7 +4613,8 @@ long ssl_get_algorithm2(SSL *s)
  * Fill a ClientRandom or ServerRandom field of length len. Returns <= 0 on
  * failure, 1 on success.
  */
-int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, size_t len,
+int ssl_fill_hello_random(SSL_CONNECTION *s, int server,
+                          unsigned char *result, size_t len,
                           DOWNGRADE dgrd)
 {
     int send_time = 0, ret;
@@ -4583,9 +4630,9 @@ int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, size_t len,
         unsigned char *p = result;
 
         l2n(Time, p);
-        ret = RAND_bytes_ex(s->ctx->libctx, p, len - 4, 0);
+        ret = RAND_bytes_ex(SSL_CONNECTION_GET_CTX(s)->libctx, p, len - 4, 0);
     } else {
-        ret = RAND_bytes_ex(s->ctx->libctx, result, len, 0);
+        ret = RAND_bytes_ex(SSL_CONNECTION_GET_CTX(s)->libctx, result, len, 0);
     }
 
     if (ret > 0) {
@@ -4603,11 +4650,12 @@ int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, size_t len,
     return ret;
 }
 
-int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
-                               int free_pms)
+int ssl_generate_master_secret(SSL_CONNECTION *s, unsigned char *pms,
+                               size_t pmslen, int free_pms)
 {
     unsigned long alg_k = s->s3.tmp.new_cipher->algorithm_mkey;
     int ret = 0;
+    SSL *ssl = SSL_CONNECTION_GET_SSL(s);
 
     if (alg_k & SSL_PSK) {
 #ifndef OPENSSL_NO_PSK
@@ -4638,7 +4686,7 @@ int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
         OPENSSL_clear_free(s->s3.tmp.psk, psklen);
         s->s3.tmp.psk = NULL;
         s->s3.tmp.psklen = 0;
-        if (!s->method->ssl3_enc->generate_master_secret(s,
+        if (!ssl->method->ssl3_enc->generate_master_secret(s,
                     s->session->master_key, pskpms, pskpmslen,
                     &s->session->master_key_length)) {
             OPENSSL_clear_free(pskpms, pskpmslen);
@@ -4651,7 +4699,7 @@ int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
         goto err;
 #endif
     } else {
-        if (!s->method->ssl3_enc->generate_master_secret(s,
+        if (!ssl->method->ssl3_enc->generate_master_secret(s,
                 s->session->master_key, pms, pmslen,
                 &s->session->master_key_length)) {
             /* SSLfatal() already called */
@@ -4675,14 +4723,15 @@ int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
 }
 
 /* Generate a private key from parameters */
-EVP_PKEY *ssl_generate_pkey(SSL *s, EVP_PKEY *pm)
+EVP_PKEY *ssl_generate_pkey(SSL_CONNECTION *s, EVP_PKEY *pm)
 {
     EVP_PKEY_CTX *pctx = NULL;
     EVP_PKEY *pkey = NULL;
+    SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
 
     if (pm == NULL)
         return NULL;
-    pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, pm, s->ctx->propq);
+    pctx = EVP_PKEY_CTX_new_from_pkey(sctx->libctx, pm, sctx->propq);
     if (pctx == NULL)
         goto err;
     if (EVP_PKEY_keygen_init(pctx) <= 0)
@@ -4698,9 +4747,10 @@ EVP_PKEY *ssl_generate_pkey(SSL *s, EVP_PKEY *pm)
 }
 
 /* Generate a private key from a group ID */
-EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id)
+EVP_PKEY *ssl_generate_pkey_group(SSL_CONNECTION *s, uint16_t id)
 {
-    const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(s->ctx, id);
+    SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
+    const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(sctx, id);
     EVP_PKEY_CTX *pctx = NULL;
     EVP_PKEY *pkey = NULL;
 
@@ -4709,11 +4759,11 @@ EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id)
         goto err;
     }
 
-    pctx = EVP_PKEY_CTX_new_from_name(s->ctx->libctx, ginf->algorithm,
-                                      s->ctx->propq);
+    pctx = EVP_PKEY_CTX_new_from_name(sctx->libctx, ginf->algorithm,
+                                      sctx->propq);
 
     if (pctx == NULL) {
-        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
+        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
         goto err;
     }
     if (EVP_PKEY_keygen_init(pctx) <= 0) {
@@ -4738,17 +4788,18 @@ EVP_PKEY *ssl_generate_pkey_group(SSL *s, uint16_t id)
 /*
  * Generate parameters from a group ID
  */
-EVP_PKEY *ssl_generate_param_group(SSL *s, uint16_t id)
+EVP_PKEY *ssl_generate_param_group(SSL_CONNECTION *s, uint16_t id)
 {
+    SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
     EVP_PKEY_CTX *pctx = NULL;
     EVP_PKEY *pkey = NULL;
-    const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(s->ctx, id);
+    const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(sctx, id);
 
     if (ginf == NULL)
         goto err;
 
-    pctx = EVP_PKEY_CTX_new_from_name(s->ctx->libctx, ginf->algorithm,
-                                      s->ctx->propq);
+    pctx = EVP_PKEY_CTX_new_from_name(sctx->libctx, ginf->algorithm,
+                                      sctx->propq);
 
     if (pctx == NULL)
         goto err;
@@ -4769,12 +4820,12 @@ EVP_PKEY *ssl_generate_param_group(SSL *s, uint16_t id)
 }
 
 /* Generate secrets from pms */
-int ssl_gensecret(SSL *s, unsigned char *pms, size_t pmslen)
+int ssl_gensecret(SSL_CONNECTION *s, unsigned char *pms, size_t pmslen)
 {
     int rv = 0;
 
     /* SSLfatal() called as appropriate in the below functions */
-    if (SSL_IS_TLS13(s)) {
+    if (SSL_CONNECTION_IS_TLS13(s)) {
         /*
          * If we are resuming then we already generated the early secret
          * when we created the ClientHello, so don't recreate it.
@@ -4795,19 +4846,20 @@ int ssl_gensecret(SSL *s, unsigned char *pms, size_t pmslen)
 }
 
 /* Derive secrets for ECDH/DH */
-int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret)
+int ssl_derive(SSL_CONNECTION *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret)
 {
     int rv = 0;
     unsigned char *pms = NULL;
     size_t pmslen = 0;
     EVP_PKEY_CTX *pctx;
+    SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
 
     if (privkey == NULL || pubkey == NULL) {
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
         return 0;
     }
 
-    pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, privkey, s->ctx->propq);
+    pctx = EVP_PKEY_CTX_new_from_pkey(sctx->libctx, privkey, sctx->propq);
 
     if (EVP_PKEY_derive_init(pctx) <= 0
         || EVP_PKEY_derive_set_peer(pctx, pubkey) <= 0
@@ -4816,12 +4868,12 @@ int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret)
         goto err;
     }
 
-    if (SSL_IS_TLS13(s) &&  EVP_PKEY_is_a(privkey, "DH"))
+    if (SSL_CONNECTION_IS_TLS13(s) &&  EVP_PKEY_is_a(privkey, "DH"))
         EVP_PKEY_CTX_set_dh_pad(pctx, 1);
 
     pms = OPENSSL_malloc(pmslen);
     if (pms == NULL) {
-        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
+        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB);
         goto err;
     }
 
@@ -4848,7 +4900,7 @@ int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret)
 }
 
 /* Decapsulate secrets for KEM */
-int ssl_decapsulate(SSL *s, EVP_PKEY *privkey,
+int ssl_decapsulate(SSL_CONNECTION *s, EVP_PKEY *privkey,
                     const unsigned char *ct, size_t ctlen,
                     int gensecret)
 {
@@ -4856,13 +4908,14 @@ int ssl_decapsulate(SSL *s, EVP_PKEY *privkey,
     unsigned char *pms = NULL;
     size_t pmslen = 0;
     EVP_PKEY_CTX *pctx;
+    SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
 
     if (privkey == NULL) {
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
         return 0;
     }
 
-    pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, privkey, s->ctx->propq);
+    pctx = EVP_PKEY_CTX_new_from_pkey(sctx->libctx, privkey, sctx->propq);
 
     if (EVP_PKEY_decapsulate_init(pctx, NULL) <= 0
             || EVP_PKEY_decapsulate(pctx, NULL, &pmslen, ct, ctlen) <= 0) {
@@ -4872,7 +4925,7 @@ int ssl_decapsulate(SSL *s, EVP_PKEY *privkey,
 
     pms = OPENSSL_malloc(pmslen);
     if (pms == NULL) {
-        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
+        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB);
         goto err;
     }
 
@@ -4898,7 +4951,7 @@ int ssl_decapsulate(SSL *s, EVP_PKEY *privkey,
     return rv;
 }
 
-int ssl_encapsulate(SSL *s, EVP_PKEY *pubkey,
+int ssl_encapsulate(SSL_CONNECTION *s, EVP_PKEY *pubkey,
                     unsigned char **ctp, size_t *ctlenp,
                     int gensecret)
 {
@@ -4906,13 +4959,14 @@ int ssl_encapsulate(SSL *s, EVP_PKEY *pubkey,
     unsigned char *pms = NULL, *ct = NULL;
     size_t pmslen = 0, ctlen = 0;
     EVP_PKEY_CTX *pctx;
+    SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
 
     if (pubkey == NULL) {
         SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
         return 0;
     }
 
-    pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, pubkey, s->ctx->propq);
+    pctx = EVP_PKEY_CTX_new_from_pkey(sctx->libctx, pubkey, sctx->propq);
 
     if (EVP_PKEY_encapsulate_init(pctx, NULL) <= 0
             || EVP_PKEY_encapsulate(pctx, NULL, &ctlen, NULL, &pmslen) <= 0
@@ -4924,7 +4978,7 @@ int ssl_encapsulate(SSL *s, EVP_PKEY *pubkey,
     pms = OPENSSL_malloc(pmslen);
     ct = OPENSSL_malloc(ctlen);
     if (pms == NULL || ct == NULL) {
-        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
+        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB);
         goto err;
     }