1c28749e9Skais /* 2c28749e9Skais * CDDL HEADER START 3c28749e9Skais * 4c28749e9Skais * The contents of this file are subject to the terms of the 5968d6ddeSkrishna * Common Development and Distribution License (the "License"). 6968d6ddeSkrishna * You may not use this file except in compliance with the License. 7c28749e9Skais * 8c28749e9Skais * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9c28749e9Skais * or http://www.opensolaris.org/os/licensing. 10c28749e9Skais * See the License for the specific language governing permissions 11c28749e9Skais * and limitations under the License. 12c28749e9Skais * 13c28749e9Skais * When distributing Covered Code, include this CDDL HEADER in each 14c28749e9Skais * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15c28749e9Skais * If applicable, add the following below this CDDL HEADER, with the 16c28749e9Skais * fields enclosed by brackets "[]" replaced with your own identifying 17c28749e9Skais * information: Portions Copyright [yyyy] [name of copyright owner] 18c28749e9Skais * 19c28749e9Skais * CDDL HEADER END 20c28749e9Skais */ 21c28749e9Skais /* 2211d0a659SVladimir Kotal * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 23c28749e9Skais */ 24c28749e9Skais 25c28749e9Skais #include <sys/types.h> 26c28749e9Skais #include <sys/stream.h> 27c28749e9Skais #include <sys/strsubr.h> 28c28749e9Skais #include <sys/stropts.h> 29c28749e9Skais #include <sys/strsun.h> 30c28749e9Skais #define _SUN_TPI_VERSION 2 31c28749e9Skais #include <sys/ddi.h> 32c28749e9Skais #include <sys/sunddi.h> 33c28749e9Skais #include <sys/debug.h> 34c28749e9Skais #include <sys/vtrace.h> 35c28749e9Skais #include <sys/kmem.h> 36c28749e9Skais #include <sys/cpuvar.h> 37c28749e9Skais #include <sys/atomic.h> 38c28749e9Skais #include <sys/sysmacros.h> 39c28749e9Skais 40c28749e9Skais #include <sys/errno.h> 41c28749e9Skais #include <sys/isa_defs.h> 42c28749e9Skais #include <sys/md5.h> 43c28749e9Skais #include <sys/sha1.h> 44c28749e9Skais #include <sys/random.h> 45c28749e9Skais #include <inet/common.h> 46c28749e9Skais #include <netinet/in.h> 47c28749e9Skais 48c28749e9Skais #include <sys/systm.h> 49c28749e9Skais #include <sys/param.h> 50c28749e9Skais 51c28749e9Skais #include "ksslimpl.h" 52c28749e9Skais #include "ksslapi.h" 53c28749e9Skais #include "ksslproto.h" 54c28749e9Skais 55c28749e9Skais static ssl3CipherSuiteDef cipher_suite_defs[] = { 562bd70d4bSkrishna /* 2 X 16 byte keys + 2 x 20 byte MAC secrets, no IVs */ 57c28749e9Skais {SSL_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, 72}, 582bd70d4bSkrishna 592bd70d4bSkrishna /* 2 X 16 byte keys + 2 x 16 byte MAC secrets, no IVs */ 60c28749e9Skais {SSL_RSA_WITH_RC4_128_MD5, cipher_rc4, mac_md5, 64}, 612bd70d4bSkrishna 622bd70d4bSkrishna /* 2 X 8 byte keys + 2 x 20 byte MAC secrets, 2 x 8 byte IVs */ 63c28749e9Skais {SSL_RSA_WITH_DES_CBC_SHA, cipher_des, mac_sha, 72}, 642bd70d4bSkrishna 652bd70d4bSkrishna /* 2 X 24 byte keys + 2 x 20 byte MAC secrets, 2 x 8 byte IVs */ 66c28749e9Skais {SSL_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, 104}, 672bd70d4bSkrishna 682bd70d4bSkrishna /* 2 X 16 byte keys + 2 x 20 byte MAC secrets, 2 x 16 byte IVs */ 692bd70d4bSkrishna {TLS_RSA_WITH_AES_128_CBC_SHA, cipher_aes128, mac_sha, 104}, 702bd70d4bSkrishna 712bd70d4bSkrishna /* 2 X 32 byte keys + 2 x 20 byte MAC secrets, 2 x 16 byte IVs */ 722bd70d4bSkrishna {TLS_RSA_WITH_AES_256_CBC_SHA, cipher_aes256, mac_sha, 136}, 732bd70d4bSkrishna 74c28749e9Skais {SSL_RSA_WITH_NULL_SHA, cipher_null, mac_sha, 40} 75c28749e9Skais }; 76c28749e9Skais 77c28749e9Skais static int cipher_suite_defs_nentries = 78c28749e9Skais sizeof (cipher_suite_defs) / sizeof (cipher_suite_defs[0]); 79c28749e9Skais 80c28749e9Skais static KSSLMACDef mac_defs[] = { /* indexed by SSL3MACAlgorithm */ 81c28749e9Skais /* macsz padsz HashInit HashUpdate HashFinal */ 82c28749e9Skais 83c28749e9Skais {MD5_HASH_LEN, SSL3_MD5_PAD_LEN, 84c28749e9Skais (hashinit_func_t)MD5Init, (hashupdate_func_t)MD5Update, 85c28749e9Skais (hashfinal_func_t)MD5Final}, 86c28749e9Skais 87c28749e9Skais {SHA1_HASH_LEN, SSL3_SHA1_PAD_LEN, 88c28749e9Skais (hashinit_func_t)SHA1Init, (hashupdate_func_t)SHA1Update, 89c28749e9Skais (hashfinal_func_t)SHA1Final}, 90c28749e9Skais }; 91c28749e9Skais 92c28749e9Skais static uchar_t kssl_pad_1[60] = { 93c28749e9Skais 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 94c28749e9Skais 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 95c28749e9Skais 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 96c28749e9Skais 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 97c28749e9Skais 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 98c28749e9Skais 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 99c28749e9Skais 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 100c28749e9Skais 0x36, 0x36, 0x36, 0x36 101c28749e9Skais }; 102c28749e9Skais static uchar_t kssl_pad_2[60] = { 103c28749e9Skais 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 104c28749e9Skais 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 105c28749e9Skais 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 106c28749e9Skais 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 107c28749e9Skais 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 108c28749e9Skais 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 109c28749e9Skais 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 110c28749e9Skais 0x5c, 0x5c, 0x5c, 0x5c 111c28749e9Skais }; 112c28749e9Skais 113c28749e9Skais static boolean_t kssl_synchronous = B_FALSE; 114c28749e9Skais 115c28749e9Skais static void kssl_update_handshake_hashes(ssl_t *, uchar_t *, uint_t); 116c28749e9Skais static int kssl_compute_handshake_hashes(ssl_t *, SSL3Hashes *, uint32_t); 117c28749e9Skais static int kssl_handle_client_hello(ssl_t *, mblk_t *, int); 118c28749e9Skais static int kssl_handle_client_key_exchange(ssl_t *, mblk_t *, int, 119c28749e9Skais kssl_callback_t, void *); 120c28749e9Skais static int kssl_send_server_hello(ssl_t *); 121c28749e9Skais static int kssl_send_certificate_and_server_hello_done(ssl_t *); 122c28749e9Skais static int kssl_send_change_cipher_specs(ssl_t *); 123c28749e9Skais static int kssl_send_finished(ssl_t *, int); 124c28749e9Skais static int kssl_handle_finished(ssl_t *, mblk_t *, int); 125c28749e9Skais static void kssl_get_hello_random(uchar_t *); 126c28749e9Skais static uchar_t *kssl_rsa_unwrap(uchar_t *, size_t *); 127c28749e9Skais static void kssl_cache_sid(sslSessionID *, kssl_entry_t *); 1282ec7cc7fSKrishna Yenduri static void kssl_lookup_sid(sslSessionID *, uchar_t *, in6_addr_t *, 129c28749e9Skais kssl_entry_t *); 130c28749e9Skais static int kssl_generate_tls_ms(ssl_t *, uchar_t *, size_t); 131c28749e9Skais static void kssl_generate_ssl_ms(ssl_t *, uchar_t *, size_t); 132c28749e9Skais static int kssl_generate_tls_keyblock(ssl_t *); 133c28749e9Skais static void kssl_generate_keyblock(ssl_t *); 134c28749e9Skais static void kssl_ssl3_key_material_derive_step(ssl_t *, uchar_t *, size_t, 135c28749e9Skais int, uchar_t *, int); 136c28749e9Skais static int kssl_tls_PRF(ssl_t *, uchar_t *, size_t, 137c28749e9Skais uchar_t *, size_t, uchar_t *, size_t, uchar_t *, size_t); 138c28749e9Skais static int kssl_tls_P_hash(crypto_mechanism_t *, crypto_key_t *, 139c28749e9Skais size_t, uchar_t *, size_t, uchar_t *, size_t, uchar_t *, size_t); 140c28749e9Skais static void kssl_cke_done(void *, int); 141c28749e9Skais 142c28749e9Skais #define HMAC_INIT(m, k, c) \ 143c28749e9Skais rv = crypto_mac_init(m, k, NULL, c, NULL); if (CRYPTO_ERR(rv)) goto end; 144c28749e9Skais 145c28749e9Skais #define HMAC_UPDATE(c, d, l) \ 146c28749e9Skais dd.cd_raw.iov_base = (char *)d; \ 147c28749e9Skais dd.cd_length = dd.cd_raw.iov_len = l; \ 148c28749e9Skais rv = crypto_mac_update(c, &dd, NULL); if (CRYPTO_ERR(rv)) goto end; 149c28749e9Skais 150c28749e9Skais #define HMAC_FINAL(c, d, l) \ 151c28749e9Skais mac.cd_raw.iov_base = (char *)d; \ 152c28749e9Skais mac.cd_length = mac.cd_raw.iov_len = l; \ 153c28749e9Skais rv = crypto_mac_final(c, &mac, NULL); if (CRYPTO_ERR(rv)) goto end; 154c28749e9Skais 155efe05f9eSkrishna /* 156efe05f9eSkrishna * This hack can go away once we have SSL3 MAC support by KCF 157efe05f9eSkrishna * software providers (See 4873559). 158efe05f9eSkrishna */ 159efe05f9eSkrishna extern int kcf_md5_threshold; 160efe05f9eSkrishna 161c28749e9Skais int 162c28749e9Skais kssl_compute_record_mac( 163c28749e9Skais ssl_t *ssl, 164c28749e9Skais int direction, 165c28749e9Skais uint64_t seq_num, 166c28749e9Skais SSL3ContentType ct, 167c28749e9Skais uchar_t *versionp, 168c28749e9Skais uchar_t *buf, 169c28749e9Skais int len, 170c28749e9Skais uchar_t *digest) 171c28749e9Skais { 172c28749e9Skais KSSL_HASHCTX mac_ctx; 173c28749e9Skais KSSL_HASHCTX *ctx = &mac_ctx; 174c28749e9Skais uchar_t temp[16], *p; 175c28749e9Skais KSSLCipherSpec *spec; 176efe05f9eSkrishna boolean_t hash_use_ok = B_FALSE; 177c28749e9Skais int rv = 0; 178c28749e9Skais 179c28749e9Skais spec = &ssl->spec[direction]; 180c28749e9Skais 181c28749e9Skais if (spec->mac_hashsz == 0) { 182c28749e9Skais return (1); 183c28749e9Skais } 184c28749e9Skais 185c28749e9Skais p = temp; 186c28749e9Skais 187c28749e9Skais *p++ = (seq_num >> 56) & 0xff; 188c28749e9Skais *p++ = (seq_num >> 48) & 0xff; 189c28749e9Skais *p++ = (seq_num >> 40) & 0xff; 190c28749e9Skais *p++ = (seq_num >> 32) & 0xff; 191c28749e9Skais *p++ = (seq_num >> 24) & 0xff; 192c28749e9Skais *p++ = (seq_num >> 16) & 0xff; 193c28749e9Skais *p++ = (seq_num >> 8) & 0xff; 194c28749e9Skais *p++ = (seq_num) & 0xff; 195c28749e9Skais *p++ = (uchar_t)ct; 196c28749e9Skais if (IS_TLS(ssl)) { 197c28749e9Skais *p++ = versionp[0]; 198c28749e9Skais *p++ = versionp[1]; 199c28749e9Skais } 200c28749e9Skais *p++ = (len >> 8) & 0xff; 201c28749e9Skais *p++ = (len) & 0xff; 202c28749e9Skais 203efe05f9eSkrishna if (IS_TLS(ssl) || (spec->hmac_mech.cm_type != CRYPTO_MECH_INVALID && 204efe05f9eSkrishna len >= kcf_md5_threshold)) { 205c28749e9Skais crypto_data_t dd, mac; 206efe05f9eSkrishna struct uio uio_pt; 207efe05f9eSkrishna struct iovec iovarray_pt[2]; 208c28749e9Skais 209efe05f9eSkrishna /* init the array of iovecs for use in the uio struct */ 210efe05f9eSkrishna iovarray_pt[0].iov_base = (char *)temp; 211efe05f9eSkrishna iovarray_pt[0].iov_len = (p - temp); 212efe05f9eSkrishna iovarray_pt[1].iov_base = (char *)buf; 213efe05f9eSkrishna iovarray_pt[1].iov_len = len; 214efe05f9eSkrishna 215efe05f9eSkrishna /* init the uio struct for use in the crypto_data_t struct */ 216efe05f9eSkrishna bzero(&uio_pt, sizeof (uio_pt)); 217efe05f9eSkrishna uio_pt.uio_iov = iovarray_pt; 218efe05f9eSkrishna uio_pt.uio_iovcnt = 2; 219efe05f9eSkrishna uio_pt.uio_segflg = UIO_SYSSPACE; 220efe05f9eSkrishna 221efe05f9eSkrishna dd.cd_format = CRYPTO_DATA_UIO; 222c28749e9Skais dd.cd_offset = 0; 223efe05f9eSkrishna dd.cd_length = (p - temp) + len; 224efe05f9eSkrishna dd.cd_miscdata = NULL; 225efe05f9eSkrishna dd.cd_uio = &uio_pt; 226efe05f9eSkrishna 227c28749e9Skais mac.cd_format = CRYPTO_DATA_RAW; 228c28749e9Skais mac.cd_offset = 0; 229efe05f9eSkrishna mac.cd_raw.iov_base = (char *)digest; 230efe05f9eSkrishna mac.cd_length = mac.cd_raw.iov_len = spec->mac_hashsz; 231c28749e9Skais 232efe05f9eSkrishna /* 233efe05f9eSkrishna * The calling context can tolerate a blocking call here. 234dd49f125SAnders Persson * For outgoing traffic, we are in user context when called 235dd49f125SAnders Persson * from kssl_data_out_cb(). For incoming traffic past the 236dd49f125SAnders Persson * SSL handshake, we are in user context when called from 237dd49f125SAnders Persson * kssl_data_in_proc_cb(). During the SSL handshake, we are 238dd49f125SAnders Persson * called for client_finished message handling from a taskq 239dd49f125SAnders Persson * thread. 240efe05f9eSkrishna */ 241efe05f9eSkrishna rv = crypto_mac(&spec->hmac_mech, &dd, &spec->hmac_key, 242efe05f9eSkrishna NULL, &mac, NULL); 243efe05f9eSkrishna 244c28749e9Skais if (CRYPTO_ERR(rv)) { 245efe05f9eSkrishna hash_use_ok = (rv == CRYPTO_MECH_NOT_SUPPORTED && 246efe05f9eSkrishna !IS_TLS(ssl)); 247efe05f9eSkrishna if (!hash_use_ok) { 24851dd2c77Svk199839 DTRACE_PROBE1(kssl_err__crypto_mac_error, 24951dd2c77Svk199839 int, rv); 250c28749e9Skais KSSL_COUNTER(compute_mac_failure, 1); 251c28749e9Skais } 252efe05f9eSkrishna } 253efe05f9eSkrishna } else 254efe05f9eSkrishna hash_use_ok = B_TRUE; 255efe05f9eSkrishna 256efe05f9eSkrishna if (hash_use_ok) { 257c28749e9Skais bcopy(&(ssl->mac_ctx[direction][0]), ctx, 258c28749e9Skais sizeof (KSSL_HASHCTX)); 259c28749e9Skais spec->MAC_HashUpdate((void *)ctx, temp, p - temp); 260c28749e9Skais spec->MAC_HashUpdate((void *)ctx, buf, len); 261c28749e9Skais spec->MAC_HashFinal(digest, (void *)ctx); 262c28749e9Skais 263c28749e9Skais bcopy(&(ssl->mac_ctx[direction][1]), ctx, 264c28749e9Skais sizeof (KSSL_HASHCTX)); 265c28749e9Skais spec->MAC_HashUpdate((void *)ctx, digest, spec->mac_hashsz); 266c28749e9Skais spec->MAC_HashFinal(digest, (void *)ctx); 267c28749e9Skais } 268c28749e9Skais 269c28749e9Skais return (rv); 270c28749e9Skais } 271c28749e9Skais 272c28749e9Skais /* 273c28749e9Skais * Handles handshake messages. 274c28749e9Skais * Messages to be replied are returned in handshake_sendbuf. 275c28749e9Skais */ 276c28749e9Skais int 277c28749e9Skais kssl_handle_handshake_message(ssl_t *ssl, mblk_t *mp, int *err, 278c28749e9Skais kssl_callback_t cbfn, void *arg) 279c28749e9Skais { 280c28749e9Skais uint32_t msglen; 281c28749e9Skais uchar_t msghdr[4]; 282c28749e9Skais 283c28749e9Skais ASSERT(ssl->msg.state == MSG_BODY); 284c28749e9Skais ASSERT(ssl->msg.msglen_bytes == 3); 285c28749e9Skais ASSERT(mp->b_wptr >= mp->b_rptr + ssl->msg.msglen); 286c28749e9Skais 287c28749e9Skais ssl->sslcnt++; 288c28749e9Skais msglen = ssl->msg.msglen; 289c28749e9Skais 290c28749e9Skais if (ssl->msg.type == client_hello) { 291c28749e9Skais MD5Init(&ssl->hs_md5); 292c28749e9Skais SHA1Init(&ssl->hs_sha1); 293c28749e9Skais } 294c28749e9Skais 295c28749e9Skais if (ssl->msg.type == finished && ssl->resumed == B_FALSE) { 296c28749e9Skais if (kssl_compute_handshake_hashes(ssl, &ssl->hs_hashes, 297c28749e9Skais sender_client) != 0) { 298c28749e9Skais *err = SSL_MISS; 299c28749e9Skais return (0); 300c28749e9Skais } 301c28749e9Skais } 302c28749e9Skais 303c28749e9Skais if (ssl->msg.type != finished || ssl->resumed == B_FALSE) { 304c28749e9Skais msghdr[0] = (uchar_t)ssl->msg.type; 305c28749e9Skais 306c28749e9Skais msghdr[1] = (uchar_t)(msglen >> 16); 307c28749e9Skais msghdr[2] = (uchar_t)(msglen >> 8); 308c28749e9Skais msghdr[3] = (uchar_t)(msglen); 309c28749e9Skais kssl_update_handshake_hashes(ssl, msghdr, 4); 310c28749e9Skais kssl_update_handshake_hashes(ssl, mp->b_rptr, msglen); 311c28749e9Skais } 312c28749e9Skais 313c28749e9Skais ssl->msg.state = MSG_INIT; 314c28749e9Skais ssl->msg.msglen = 0; 315c28749e9Skais ssl->msg.msglen_bytes = 0; 316c28749e9Skais 317c28749e9Skais switch (ssl->msg.type) { 318c28749e9Skais case client_hello: 319c28749e9Skais if (ssl->hs_waitstate != wait_client_hello) { 320c28749e9Skais kssl_send_alert(ssl, alert_fatal, 321c28749e9Skais unexpected_message); 322c28749e9Skais *err = EBADMSG; 323c28749e9Skais ssl->activeinput = B_FALSE; 324c28749e9Skais return (1); 325c28749e9Skais } 326c28749e9Skais *err = kssl_handle_client_hello(ssl, mp, msglen); 327c28749e9Skais if (*err == SSL_MISS) { 328c28749e9Skais ssl->activeinput = B_FALSE; 329c28749e9Skais return (0); 330c28749e9Skais } 331c28749e9Skais return (1); 332c28749e9Skais case client_key_exchange: 333c28749e9Skais if (ssl->hs_waitstate != wait_client_key) { 334c28749e9Skais kssl_send_alert(ssl, alert_fatal, 335c28749e9Skais unexpected_message); 336c28749e9Skais *err = EBADMSG; 337c28749e9Skais ssl->activeinput = B_FALSE; 338c28749e9Skais return (1); 339c28749e9Skais } 340c28749e9Skais *err = kssl_handle_client_key_exchange(ssl, mp, 341c28749e9Skais msglen, cbfn, arg); 342c28749e9Skais return (1); 343c28749e9Skais case finished: 344c28749e9Skais if (ssl->hs_waitstate != wait_finished) { 345c28749e9Skais kssl_send_alert(ssl, alert_fatal, 346c28749e9Skais unexpected_message); 347c28749e9Skais *err = EBADMSG; 348c28749e9Skais ssl->activeinput = B_FALSE; 349c28749e9Skais return (1); 350c28749e9Skais } 351c28749e9Skais *err = kssl_handle_finished(ssl, mp, msglen); 352c28749e9Skais return (1); 353c28749e9Skais default: 354c28749e9Skais kssl_send_alert(ssl, alert_fatal, unexpected_message); 355c28749e9Skais ssl->activeinput = B_FALSE; 356c28749e9Skais *err = EBADMSG; 357c28749e9Skais return (1); 358c28749e9Skais } 359c28749e9Skais } 360c28749e9Skais 361c28749e9Skais static void 362c28749e9Skais kssl_update_handshake_hashes(ssl_t *ssl, uchar_t *buf, uint_t len) 363c28749e9Skais { 364c28749e9Skais MD5Update(&ssl->hs_md5, buf, len); 365c28749e9Skais SHA1Update(&ssl->hs_sha1, buf, len); 366c28749e9Skais } 367c28749e9Skais 368c28749e9Skais static int 369c28749e9Skais kssl_compute_handshake_hashes( 370c28749e9Skais ssl_t *ssl, 371c28749e9Skais SSL3Hashes *hashes, 372c28749e9Skais uint32_t sender) 373c28749e9Skais { 374c28749e9Skais MD5_CTX md5 = ssl->hs_md5; /* clone md5 context */ 375c28749e9Skais SHA1_CTX sha1 = ssl->hs_sha1; /* clone sha1 context */ 376c28749e9Skais MD5_CTX *md5ctx = &md5; 377c28749e9Skais SHA1_CTX *sha1ctx = &sha1; 378c28749e9Skais 379c28749e9Skais if (IS_TLS(ssl)) { 380c28749e9Skais uchar_t seed[MD5_HASH_LEN + SHA1_HASH_LEN]; 381c28749e9Skais char *label; 382c28749e9Skais 383c28749e9Skais /* 384c28749e9Skais * Do not take another hash step here. 385c28749e9Skais * Just complete the operation. 386c28749e9Skais */ 387c28749e9Skais MD5Final(hashes->md5, md5ctx); 388c28749e9Skais SHA1Final(hashes->sha1, sha1ctx); 389c28749e9Skais 390c28749e9Skais bcopy(hashes->md5, seed, MD5_HASH_LEN); 391c28749e9Skais bcopy(hashes->sha1, seed + MD5_HASH_LEN, SHA1_HASH_LEN); 392c28749e9Skais 393c28749e9Skais if (sender == sender_client) 394c28749e9Skais label = TLS_CLIENT_FINISHED_LABEL; 395c28749e9Skais else 396c28749e9Skais label = TLS_SERVER_FINISHED_LABEL; 397c28749e9Skais 398c28749e9Skais return (kssl_tls_PRF(ssl, 39951dd2c77Svk199839 ssl->sid.master_secret, 40051dd2c77Svk199839 (size_t)SSL3_MASTER_SECRET_LEN, 401c28749e9Skais (uchar_t *)label, strlen(label), 402c28749e9Skais seed, (size_t)(MD5_HASH_LEN + SHA1_HASH_LEN), 403c28749e9Skais hashes->tlshash, (size_t)TLS_FINISHED_SIZE)); 404c28749e9Skais } else { 405c28749e9Skais uchar_t s[4]; 406c28749e9Skais s[0] = (sender >> 24) & 0xff; 407c28749e9Skais s[1] = (sender >> 16) & 0xff; 408c28749e9Skais s[2] = (sender >> 8) & 0xff; 409c28749e9Skais s[3] = (sender) & 0xff; 410c28749e9Skais 411c28749e9Skais MD5Update(md5ctx, s, 4); 412c28749e9Skais MD5Update(md5ctx, ssl->sid.master_secret, 413c28749e9Skais SSL3_MASTER_SECRET_LEN); 414c28749e9Skais MD5Update(md5ctx, kssl_pad_1, SSL3_MD5_PAD_LEN); 415c28749e9Skais MD5Final(hashes->md5, md5ctx); 416c28749e9Skais 417c28749e9Skais MD5Init(md5ctx); 418c28749e9Skais MD5Update(md5ctx, ssl->sid.master_secret, 419c28749e9Skais SSL3_MASTER_SECRET_LEN); 420c28749e9Skais MD5Update(md5ctx, kssl_pad_2, SSL3_MD5_PAD_LEN); 421c28749e9Skais MD5Update(md5ctx, hashes->md5, MD5_HASH_LEN); 422c28749e9Skais MD5Final(hashes->md5, md5ctx); 423c28749e9Skais 424c28749e9Skais SHA1Update(sha1ctx, s, 4); 425c28749e9Skais SHA1Update(sha1ctx, ssl->sid.master_secret, 426c28749e9Skais SSL3_MASTER_SECRET_LEN); 427c28749e9Skais SHA1Update(sha1ctx, kssl_pad_1, SSL3_SHA1_PAD_LEN); 428c28749e9Skais SHA1Final(hashes->sha1, sha1ctx); 429c28749e9Skais 430c28749e9Skais SHA1Init(sha1ctx); 431c28749e9Skais SHA1Update(sha1ctx, ssl->sid.master_secret, 432c28749e9Skais SSL3_MASTER_SECRET_LEN); 433c28749e9Skais SHA1Update(sha1ctx, kssl_pad_2, SSL3_SHA1_PAD_LEN); 434c28749e9Skais SHA1Update(sha1ctx, hashes->sha1, SHA1_HASH_LEN); 435c28749e9Skais SHA1Final(hashes->sha1, sha1ctx); 436c28749e9Skais return (0); 437c28749e9Skais } 438c28749e9Skais } 439c28749e9Skais 440c28749e9Skais 44151144063SKrishna Yenduri /* 44251144063SKrishna Yenduri * Minimum message length for a client hello = 44351144063SKrishna Yenduri * 2-byte client_version + 44451144063SKrishna Yenduri * 32-byte random + 44551144063SKrishna Yenduri * 1-byte session_id length + 44651144063SKrishna Yenduri * 2-byte cipher_suites length + 44751144063SKrishna Yenduri * 1-byte compression_methods length + 44851144063SKrishna Yenduri * 1-byte CompressionMethod.null 44951144063SKrishna Yenduri */ 450c28749e9Skais #define KSSL_SSL3_CH_MIN_MSGLEN (39) 451c28749e9Skais 45265d18457SVladimir Kotal /* 45365d18457SVladimir Kotal * Process SSL/TLS Client Hello message. Return 0 on success, errno value 45465d18457SVladimir Kotal * or SSL_MISS if no cipher suite of the server matches the list received 45565d18457SVladimir Kotal * in the message. 45665d18457SVladimir Kotal */ 457c28749e9Skais static int 458c28749e9Skais kssl_handle_client_hello(ssl_t *ssl, mblk_t *mp, int msglen) 459c28749e9Skais { 460c28749e9Skais uchar_t *msgend; 461c28749e9Skais int err; 462c28749e9Skais SSL3AlertDescription desc = illegal_parameter; 46351144063SKrishna Yenduri uint_t sidlen, cslen, cmlen; 464c28749e9Skais uchar_t *suitesp; 465c28749e9Skais uint_t i, j; 46611d0a659SVladimir Kotal uint16_t suite, selected_suite; 467c28749e9Skais int ch_msglen = KSSL_SSL3_CH_MIN_MSGLEN; 46811d0a659SVladimir Kotal boolean_t suite_found = B_FALSE; 469c28749e9Skais 470c28749e9Skais ASSERT(mp->b_wptr >= mp->b_rptr + msglen); 471c28749e9Skais ASSERT(ssl->msg.type == client_hello); 472c28749e9Skais ASSERT(ssl->hs_waitstate == wait_client_hello); 473c28749e9Skais ASSERT(ssl->resumed == B_FALSE); 474c28749e9Skais 475c28749e9Skais if (msglen < ch_msglen) { 47665d18457SVladimir Kotal DTRACE_PROBE2(kssl_err__msglen_less_than_minimum, 47765d18457SVladimir Kotal int, msglen, int, ch_msglen); 478c28749e9Skais goto falert; 479c28749e9Skais } 480c28749e9Skais 481c28749e9Skais msgend = mp->b_rptr + msglen; 482c28749e9Skais 483c28749e9Skais /* Support SSLv3 (version == 3.0) or TLS (version == 3.1) */ 484c28749e9Skais if (ssl->major_version != 3 || (ssl->major_version == 3 && 485c28749e9Skais ssl->minor_version != 0 && ssl->minor_version != 1)) { 48651dd2c77Svk199839 DTRACE_PROBE2(kssl_err__SSL_version_not_supported, 48751dd2c77Svk199839 uchar_t, ssl->major_version, 48851dd2c77Svk199839 uchar_t, ssl->minor_version); 489c28749e9Skais desc = handshake_failure; 490c28749e9Skais goto falert; 491c28749e9Skais } 492c28749e9Skais mp->b_rptr += 2; /* skip the version bytes */ 493c28749e9Skais 49465d18457SVladimir Kotal /* read client random field */ 495c28749e9Skais bcopy(mp->b_rptr, ssl->client_random, SSL3_RANDOM_LENGTH); 496c28749e9Skais mp->b_rptr += SSL3_RANDOM_LENGTH; 497c28749e9Skais 49865d18457SVladimir Kotal /* read session ID length */ 499c28749e9Skais ASSERT(ssl->sid.cached == B_FALSE); 500c28749e9Skais sidlen = *mp->b_rptr++; 501c28749e9Skais ch_msglen += sidlen; 502c28749e9Skais if (msglen < ch_msglen) { 50365d18457SVladimir Kotal DTRACE_PROBE2(kssl_err__invalid_message_length_after_ver, 50465d18457SVladimir Kotal int, msglen, int, ch_msglen); 505c28749e9Skais goto falert; 506c28749e9Skais } 507c28749e9Skais if (sidlen != SSL3_SESSIONID_BYTES) { 508c28749e9Skais mp->b_rptr += sidlen; 509c28749e9Skais } else { 5102ec7cc7fSKrishna Yenduri kssl_lookup_sid(&ssl->sid, mp->b_rptr, &ssl->faddr, 511c28749e9Skais ssl->kssl_entry); 512c28749e9Skais mp->b_rptr += SSL3_SESSIONID_BYTES; 513c28749e9Skais } 514c28749e9Skais 51565d18457SVladimir Kotal /* read cipher suite length */ 51651144063SKrishna Yenduri cslen = ((uint_t)mp->b_rptr[0] << 8) + (uint_t)mp->b_rptr[1]; 517c28749e9Skais mp->b_rptr += 2; 51851144063SKrishna Yenduri ch_msglen += cslen; 51951144063SKrishna Yenduri 52051144063SKrishna Yenduri /* 52151144063SKrishna Yenduri * This check can't be a "!=" since there can be 52251144063SKrishna Yenduri * compression methods other than CompressionMethod.null. 52351144063SKrishna Yenduri * Also, there can be extra data (TLS extensions) after the 52411d0a659SVladimir Kotal * compression methods field. 52551144063SKrishna Yenduri */ 52651144063SKrishna Yenduri if (msglen < ch_msglen) { 52765d18457SVladimir Kotal DTRACE_PROBE2(kssl_err__invalid_message_length_after_cslen, 52865d18457SVladimir Kotal int, msglen, int, ch_msglen); 529c28749e9Skais goto falert; 530c28749e9Skais } 53151144063SKrishna Yenduri 53211d0a659SVladimir Kotal /* The length has to be even since a cipher suite is 2-byte long. */ 53351144063SKrishna Yenduri if (cslen & 0x1) { 53465d18457SVladimir Kotal DTRACE_PROBE1(kssl_err__uneven_cipher_suite_length, 53565d18457SVladimir Kotal uint_t, cslen); 536c28749e9Skais goto falert; 537c28749e9Skais } 538c28749e9Skais suitesp = mp->b_rptr; 53911d0a659SVladimir Kotal 54011d0a659SVladimir Kotal /* session resumption checks */ 541c28749e9Skais if (ssl->sid.cached == B_TRUE) { 542c28749e9Skais suite = ssl->sid.cipher_suite; 54351144063SKrishna Yenduri for (j = 0; j < cslen; j += 2) { 54411d0a659SVladimir Kotal DTRACE_PROBE2(kssl_cipher_suite_check_resumpt, 54511d0a659SVladimir Kotal uint16_t, suite, 54611d0a659SVladimir Kotal uint16_t, 54711d0a659SVladimir Kotal (uint16_t)((suitesp[j] << 8) + suitesp[j+1])); 54811d0a659SVladimir Kotal /* Check for regular (true) cipher suite. */ 549c28749e9Skais if (suitesp[j] == ((suite >> 8) & 0xff) && 550c28749e9Skais suitesp[j + 1] == (suite & 0xff)) { 55111d0a659SVladimir Kotal DTRACE_PROBE1(kssl_cipher_suite_found_resumpt, 55211d0a659SVladimir Kotal uint16_t, suite); 55311d0a659SVladimir Kotal suite_found = B_TRUE; 55411d0a659SVladimir Kotal selected_suite = suite; 55511d0a659SVladimir Kotal } 55611d0a659SVladimir Kotal 55711d0a659SVladimir Kotal /* Check for SCSV. */ 55811d0a659SVladimir Kotal if (suitesp[j] == ((SSL_SCSV >> 8) & 0xff) && 55911d0a659SVladimir Kotal suitesp[j + 1] == (SSL_SCSV & 0xff)) { 56011d0a659SVladimir Kotal DTRACE_PROBE(kssl_scsv_found_resumpt); 56111d0a659SVladimir Kotal ssl->secure_renegotiation = B_TRUE; 56211d0a659SVladimir Kotal } 56311d0a659SVladimir Kotal 56411d0a659SVladimir Kotal /* 56511d0a659SVladimir Kotal * If we got cipher suite match and SCSV we can 56611d0a659SVladimir Kotal * terminate the cycle now. 56711d0a659SVladimir Kotal */ 56811d0a659SVladimir Kotal if (suite_found && ssl->secure_renegotiation) 569c28749e9Skais break; 570c28749e9Skais } 57111d0a659SVladimir Kotal if (suite_found) 572c28749e9Skais goto suite_found; 573c28749e9Skais kssl_uncache_sid(&ssl->sid, ssl->kssl_entry); 574c28749e9Skais } 575c28749e9Skais 57611d0a659SVladimir Kotal /* Check if this server is capable of the cipher suite. */ 577c28749e9Skais for (i = 0; i < ssl->kssl_entry->kssl_cipherSuites_nentries; i++) { 578c28749e9Skais suite = ssl->kssl_entry->kssl_cipherSuites[i]; 57951144063SKrishna Yenduri for (j = 0; j < cslen; j += 2) { 58011d0a659SVladimir Kotal DTRACE_PROBE2(kssl_cipher_suite_check, uint16_t, suite, 58111d0a659SVladimir Kotal uint16_t, 58211d0a659SVladimir Kotal (uint16_t)((suitesp[j] << 8) + suitesp[j+1])); 58311d0a659SVladimir Kotal /* Check for regular (true) cipher suite. */ 584c28749e9Skais if (suitesp[j] == ((suite >> 8) & 0xff) && 585c28749e9Skais suitesp[j + 1] == (suite & 0xff)) { 58611d0a659SVladimir Kotal DTRACE_PROBE1(kssl_cipher_suite_found, 58711d0a659SVladimir Kotal uint16_t, suite); 58811d0a659SVladimir Kotal suite_found = B_TRUE; 58911d0a659SVladimir Kotal selected_suite = suite; 59011d0a659SVladimir Kotal } 59111d0a659SVladimir Kotal 59211d0a659SVladimir Kotal /* Check for SCSV. */ 59311d0a659SVladimir Kotal if (suitesp[j] == ((SSL_SCSV >> 8) & 0xff) && 59411d0a659SVladimir Kotal suitesp[j + 1] == (SSL_SCSV & 0xff)) { 59511d0a659SVladimir Kotal DTRACE_PROBE(kssl_scsv_found); 59611d0a659SVladimir Kotal ssl->secure_renegotiation = B_TRUE; 59711d0a659SVladimir Kotal } 59811d0a659SVladimir Kotal 59911d0a659SVladimir Kotal /* 60011d0a659SVladimir Kotal * If we got cipher suite match and SCSV or went 60111d0a659SVladimir Kotal * through the whole list of client cipher suites 60211d0a659SVladimir Kotal * (hence we know if SCSV was present or not) we 60311d0a659SVladimir Kotal * can terminate the cycle now. 60411d0a659SVladimir Kotal */ 60511d0a659SVladimir Kotal if (suite_found && 60611d0a659SVladimir Kotal (ssl->secure_renegotiation || (i > 0))) 607c28749e9Skais break; 608c28749e9Skais } 60911d0a659SVladimir Kotal if (suite_found) 610c28749e9Skais break; 611c28749e9Skais } 61211d0a659SVladimir Kotal if (!suite_found) { 613c28749e9Skais if (ssl->sslcnt == 1) { 61465d18457SVladimir Kotal DTRACE_PROBE(kssl_no_cipher_suite_found); 615c28749e9Skais KSSL_COUNTER(no_suite_found, 1); 61665d18457SVladimir Kotal /* 61765d18457SVladimir Kotal * If there is no fallback point terminate the 61865d18457SVladimir Kotal * handshake with SSL alert otherwise return with 61965d18457SVladimir Kotal * SSL_MISS. 62065d18457SVladimir Kotal */ 62165d18457SVladimir Kotal if (ssl->kssl_entry->ke_fallback_head == NULL) { 62265d18457SVladimir Kotal DTRACE_PROBE(kssl_no_fallback); 62365d18457SVladimir Kotal desc = handshake_failure; 62465d18457SVladimir Kotal goto falert; 62565d18457SVladimir Kotal } else { 626c28749e9Skais return (SSL_MISS); 627c28749e9Skais } 62865d18457SVladimir Kotal } 629c28749e9Skais desc = handshake_failure; 63051dd2c77Svk199839 DTRACE_PROBE(kssl_err__no_cipher_suites_found); 631c28749e9Skais goto falert; 632c28749e9Skais } 633c28749e9Skais 634c28749e9Skais suite_found: 63551144063SKrishna Yenduri mp->b_rptr += cslen; 636c28749e9Skais 63751144063SKrishna Yenduri /* 63851144063SKrishna Yenduri * Check for the mandatory CompressionMethod.null. We do not 63951144063SKrishna Yenduri * support any other compression methods. 64051144063SKrishna Yenduri */ 64151144063SKrishna Yenduri cmlen = *mp->b_rptr++; 64251144063SKrishna Yenduri ch_msglen += cmlen - 1; /* -1 accounts for the null method */ 64351144063SKrishna Yenduri if (msglen < ch_msglen) { 64465d18457SVladimir Kotal DTRACE_PROBE2(kssl_err__invalid_message_length_after_complen, 64565d18457SVladimir Kotal int, msglen, int, ch_msglen); 64651144063SKrishna Yenduri goto falert; 64751144063SKrishna Yenduri } 64851144063SKrishna Yenduri 64965d18457SVladimir Kotal /* 65065d18457SVladimir Kotal * Search for null compression method (encoded as 0 byte) in the 65165d18457SVladimir Kotal * compression methods field. 65265d18457SVladimir Kotal */ 65351144063SKrishna Yenduri while (cmlen >= 1) { 65451144063SKrishna Yenduri if (*mp->b_rptr++ == 0) 65551144063SKrishna Yenduri break; 65651144063SKrishna Yenduri cmlen--; 65751144063SKrishna Yenduri } 65851144063SKrishna Yenduri 65951144063SKrishna Yenduri if (cmlen == 0) { 660c28749e9Skais desc = handshake_failure; 66165d18457SVladimir Kotal DTRACE_PROBE(kssl_err__no_null_compression_method); 662c28749e9Skais goto falert; 663c28749e9Skais } 664c28749e9Skais 66511d0a659SVladimir Kotal /* Find the suite in the internal cipher suite table. */ 666c28749e9Skais for (i = 0; i < cipher_suite_defs_nentries; i++) { 66711d0a659SVladimir Kotal if (selected_suite == cipher_suite_defs[i].suite) { 668c28749e9Skais break; 669c28749e9Skais } 670c28749e9Skais } 671c28749e9Skais 67211d0a659SVladimir Kotal /* Get past the remaining compression methods (minus null method). */ 67311d0a659SVladimir Kotal mp->b_rptr += cmlen - 1; 67411d0a659SVladimir Kotal 675c28749e9Skais ASSERT(i < cipher_suite_defs_nentries); 676c28749e9Skais 67711d0a659SVladimir Kotal ssl->pending_cipher_suite = selected_suite; 678c28749e9Skais ssl->pending_malg = cipher_suite_defs[i].malg; 679c28749e9Skais ssl->pending_calg = cipher_suite_defs[i].calg; 680c28749e9Skais ssl->pending_keyblksz = cipher_suite_defs[i].keyblksz; 681c28749e9Skais 68211d0a659SVladimir Kotal /* Parse TLS extensions (if any). */ 68311d0a659SVladimir Kotal if (ch_msglen + 2 < msglen) { 68411d0a659SVladimir Kotal /* Get the length of the extensions. */ 68511d0a659SVladimir Kotal uint16_t ext_total_len = ((uint_t)mp->b_rptr[0] << 8) + 68611d0a659SVladimir Kotal (uint_t)mp->b_rptr[1]; 68711d0a659SVladimir Kotal DTRACE_PROBE1(kssl_total_length_extensions, uint16_t, 68811d0a659SVladimir Kotal ext_total_len); 68911d0a659SVladimir Kotal /* 69011d0a659SVladimir Kotal * Consider zero extensions length as invalid extension 69111d0a659SVladimir Kotal * encoding. 69211d0a659SVladimir Kotal */ 69311d0a659SVladimir Kotal if (ext_total_len == 0) { 69411d0a659SVladimir Kotal DTRACE_PROBE1(kssl_err__zero_extensions_length, 69511d0a659SVladimir Kotal mblk_t *, mp); 69611d0a659SVladimir Kotal goto falert; 69711d0a659SVladimir Kotal } 69811d0a659SVladimir Kotal ch_msglen += 2; 69911d0a659SVladimir Kotal if (ch_msglen + ext_total_len > msglen) { 70011d0a659SVladimir Kotal DTRACE_PROBE2(kssl_err__invalid_extensions_length, 70111d0a659SVladimir Kotal int, msglen, int, ch_msglen); 70211d0a659SVladimir Kotal goto falert; 70311d0a659SVladimir Kotal } 70411d0a659SVladimir Kotal mp->b_rptr += 2; 70511d0a659SVladimir Kotal 70611d0a659SVladimir Kotal /* 70711d0a659SVladimir Kotal * Go through the TLS extensions. This is only done to check 70811d0a659SVladimir Kotal * for the presence of renegotiation_info extension. We do not 70911d0a659SVladimir Kotal * support any other TLS extensions and hence ignore them. 71011d0a659SVladimir Kotal */ 71111d0a659SVladimir Kotal while (mp->b_rptr < msgend) { 71211d0a659SVladimir Kotal uint16_t ext_len, ext_type; 71311d0a659SVladimir Kotal 71411d0a659SVladimir Kotal /* 71511d0a659SVladimir Kotal * Check that the extension has at least type and 71611d0a659SVladimir Kotal * length (2 + 2 bytes). 71711d0a659SVladimir Kotal */ 71811d0a659SVladimir Kotal if (ch_msglen + 4 > msglen) { 71911d0a659SVladimir Kotal DTRACE_PROBE(kssl_err__invalid_ext_format); 72011d0a659SVladimir Kotal goto falert; 72111d0a659SVladimir Kotal } 72211d0a659SVladimir Kotal 72311d0a659SVladimir Kotal /* Get extension type and length */ 72411d0a659SVladimir Kotal ext_type = ((uint_t)mp->b_rptr[0] << 8) + 72511d0a659SVladimir Kotal (uint_t)mp->b_rptr[1]; 72611d0a659SVladimir Kotal mp->b_rptr += 2; 72711d0a659SVladimir Kotal ext_len = ((uint_t)mp->b_rptr[0] << 8) + 72811d0a659SVladimir Kotal (uint_t)mp->b_rptr[1]; 72911d0a659SVladimir Kotal mp->b_rptr += 2; 73011d0a659SVladimir Kotal ch_msglen += 4; 73111d0a659SVladimir Kotal DTRACE_PROBE3(kssl_ext_detected, uint16_t, ext_type, 73211d0a659SVladimir Kotal uint16_t, ext_len, mblk_t *, mp); 73311d0a659SVladimir Kotal 73411d0a659SVladimir Kotal /* 73511d0a659SVladimir Kotal * Make sure the contents of the extension are 73611d0a659SVladimir Kotal * accessible. 73711d0a659SVladimir Kotal */ 73811d0a659SVladimir Kotal if (ch_msglen + ext_len > msglen) { 73911d0a659SVladimir Kotal DTRACE_PROBE1( 74011d0a659SVladimir Kotal kssl_err__invalid_ext_len, 74111d0a659SVladimir Kotal uint16_t, ext_len); 74211d0a659SVladimir Kotal goto falert; 74311d0a659SVladimir Kotal } 74411d0a659SVladimir Kotal 74511d0a659SVladimir Kotal switch (ext_type) { 74611d0a659SVladimir Kotal case TLSEXT_RENEGOTIATION_INFO: 74711d0a659SVladimir Kotal /* 74811d0a659SVladimir Kotal * Search for empty "renegotiation_info" 74911d0a659SVladimir Kotal * extension (encoded as ff 01 00 01 00). 75011d0a659SVladimir Kotal */ 75111d0a659SVladimir Kotal DTRACE_PROBE(kssl_reneg_info_found); 75211d0a659SVladimir Kotal if ((ext_len != 1) || 75311d0a659SVladimir Kotal (*mp->b_rptr != 0)) { 75411d0a659SVladimir Kotal DTRACE_PROBE2( 75511d0a659SVladimir Kotal kssl_err__non_empty_reneg_info, 75611d0a659SVladimir Kotal uint16_t, ext_len, 75711d0a659SVladimir Kotal mblk_t *, mp); 75811d0a659SVladimir Kotal goto falert; 75911d0a659SVladimir Kotal } 76011d0a659SVladimir Kotal ssl->secure_renegotiation = B_TRUE; 76111d0a659SVladimir Kotal break; 76211d0a659SVladimir Kotal default: 76311d0a659SVladimir Kotal /* FALLTHRU */ 76411d0a659SVladimir Kotal break; 76511d0a659SVladimir Kotal } 76611d0a659SVladimir Kotal 76711d0a659SVladimir Kotal /* jump to the next extension */ 76811d0a659SVladimir Kotal ch_msglen += ext_len; 76911d0a659SVladimir Kotal mp->b_rptr += ext_len; 77011d0a659SVladimir Kotal } 77111d0a659SVladimir Kotal } 77211d0a659SVladimir Kotal 77311d0a659SVladimir Kotal mp->b_rptr = msgend; 77411d0a659SVladimir Kotal 775c28749e9Skais if (ssl->sid.cached == B_TRUE) { 776c28749e9Skais err = kssl_send_server_hello(ssl); 777c28749e9Skais if (err != 0) { 778c28749e9Skais return (err); 779c28749e9Skais } 780c28749e9Skais if (IS_TLS(ssl)) 781c28749e9Skais err = kssl_generate_tls_keyblock(ssl); 782c28749e9Skais else 783c28749e9Skais kssl_generate_keyblock(ssl); 784c28749e9Skais 785c28749e9Skais err = kssl_send_change_cipher_specs(ssl); 786c28749e9Skais if (err != 0) { 787c28749e9Skais return (err); 788c28749e9Skais } 789c28749e9Skais 790c28749e9Skais err = kssl_send_finished(ssl, 1); 791c28749e9Skais if (err != 0) 792c28749e9Skais return (err); 793c28749e9Skais 794c28749e9Skais err = kssl_compute_handshake_hashes(ssl, &ssl->hs_hashes, 795c28749e9Skais sender_client); 796c28749e9Skais if (err != 0) 797c28749e9Skais return (err); 798c28749e9Skais 799c28749e9Skais ssl->hs_waitstate = wait_change_cipher; 800c28749e9Skais ssl->resumed = B_TRUE; 801c28749e9Skais ssl->activeinput = B_FALSE; 802c28749e9Skais KSSL_COUNTER(resumed_sessions, 1); 803c28749e9Skais return (0); 804c28749e9Skais } 805c28749e9Skais 806c28749e9Skais (void) random_get_pseudo_bytes(ssl->sid.session_id, 807c28749e9Skais SSL3_SESSIONID_BYTES); 808c28749e9Skais ssl->sid.client_addr = ssl->faddr; 80911d0a659SVladimir Kotal ssl->sid.cipher_suite = selected_suite; 810c28749e9Skais 811c28749e9Skais err = kssl_send_server_hello(ssl); 812c28749e9Skais if (err != 0) { 813c28749e9Skais return (err); 814c28749e9Skais } 815c28749e9Skais err = kssl_send_certificate_and_server_hello_done(ssl); 816c28749e9Skais if (err != 0) { 817c28749e9Skais return (err); 818c28749e9Skais } 819c28749e9Skais KSSL_COUNTER(full_handshakes, 1); 820c28749e9Skais ssl->hs_waitstate = wait_client_key; 821c28749e9Skais ssl->activeinput = B_FALSE; 822c28749e9Skais return (0); 823c28749e9Skais 824c28749e9Skais falert: 825c28749e9Skais kssl_send_alert(ssl, alert_fatal, desc); 826c28749e9Skais return (EBADMSG); 827c28749e9Skais } 828c28749e9Skais 8292ec7cc7fSKrishna Yenduri #define SET_HASH_INDEX(index, s, clnt_addr) { \ 8302ec7cc7fSKrishna Yenduri int addr; \ 8312ec7cc7fSKrishna Yenduri \ 8322ec7cc7fSKrishna Yenduri IN6_V4MAPPED_TO_IPADDR(clnt_addr, addr); \ 8332ec7cc7fSKrishna Yenduri index = addr ^ (((int)(s)[0] << 24) | ((int)(s)[1] << 16) | \ 8342ec7cc7fSKrishna Yenduri ((int)(s)[2] << 8) | (int)(s)[SSL3_SESSIONID_BYTES - 1]); \ 8352ec7cc7fSKrishna Yenduri } 8362ec7cc7fSKrishna Yenduri 8372ec7cc7fSKrishna Yenduri /* 8382ec7cc7fSKrishna Yenduri * Creates a cache entry. Sets the sid->cached flag 8392ec7cc7fSKrishna Yenduri * and sid->time fields. So, the caller should not set them. 8402ec7cc7fSKrishna Yenduri */ 841c28749e9Skais static void 842c28749e9Skais kssl_cache_sid(sslSessionID *sid, kssl_entry_t *kssl_entry) 843c28749e9Skais { 844c28749e9Skais uint_t index; 845c28749e9Skais uchar_t *s = sid->session_id; 846c28749e9Skais kmutex_t *lock; 847c28749e9Skais 8482ec7cc7fSKrishna Yenduri ASSERT(sid->cached == B_FALSE); 849c28749e9Skais 8502ec7cc7fSKrishna Yenduri /* set the values before creating the cache entry */ 8512ec7cc7fSKrishna Yenduri sid->cached = B_TRUE; 852d3d50737SRafael Vanoni sid->time = ddi_get_lbolt(); 853c28749e9Skais 8542ec7cc7fSKrishna Yenduri SET_HASH_INDEX(index, s, &sid->client_addr); 8552ec7cc7fSKrishna Yenduri index %= kssl_entry->sid_cache_nentries; 8562ec7cc7fSKrishna Yenduri 857c28749e9Skais lock = &(kssl_entry->sid_cache[index].se_lock); 858c28749e9Skais mutex_enter(lock); 859c28749e9Skais kssl_entry->sid_cache[index].se_used++; 860c28749e9Skais bcopy(sid, &(kssl_entry->sid_cache[index].se_sid), sizeof (*sid)); 861c28749e9Skais mutex_exit(lock); 8622ec7cc7fSKrishna Yenduri 8632ec7cc7fSKrishna Yenduri KSSL_COUNTER(sid_cached, 1); 864c28749e9Skais } 865c28749e9Skais 8662ec7cc7fSKrishna Yenduri /* 8672ec7cc7fSKrishna Yenduri * Invalidates the cache entry, if any. Clears the sid->cached flag 8682ec7cc7fSKrishna Yenduri * as a side effect. 8692ec7cc7fSKrishna Yenduri */ 8702ec7cc7fSKrishna Yenduri void 8712ec7cc7fSKrishna Yenduri kssl_uncache_sid(sslSessionID *sid, kssl_entry_t *kssl_entry) 872c28749e9Skais { 873c28749e9Skais uint_t index; 8742ec7cc7fSKrishna Yenduri uchar_t *s = sid->session_id; 875c28749e9Skais sslSessionID *csid; 8762ec7cc7fSKrishna Yenduri kmutex_t *lock; 877c28749e9Skais 8782ec7cc7fSKrishna Yenduri ASSERT(sid->cached == B_TRUE); 8792ec7cc7fSKrishna Yenduri sid->cached = B_FALSE; 880c28749e9Skais 8812ec7cc7fSKrishna Yenduri SET_HASH_INDEX(index, s, &sid->client_addr); 882c28749e9Skais index %= kssl_entry->sid_cache_nentries; 883c28749e9Skais 884c28749e9Skais lock = &(kssl_entry->sid_cache[index].se_lock); 885c28749e9Skais mutex_enter(lock); 886c28749e9Skais csid = &(kssl_entry->sid_cache[index].se_sid); 8872ec7cc7fSKrishna Yenduri if (!(IN6_ARE_ADDR_EQUAL(&csid->client_addr, &sid->client_addr)) || 8882ec7cc7fSKrishna Yenduri bcmp(csid->session_id, s, SSL3_SESSIONID_BYTES)) { 8892ec7cc7fSKrishna Yenduri mutex_exit(lock); 8902ec7cc7fSKrishna Yenduri return; 8912ec7cc7fSKrishna Yenduri } 8922ec7cc7fSKrishna Yenduri csid->cached = B_FALSE; 8932ec7cc7fSKrishna Yenduri mutex_exit(lock); 8942ec7cc7fSKrishna Yenduri 8952ec7cc7fSKrishna Yenduri KSSL_COUNTER(sid_uncached, 1); 8962ec7cc7fSKrishna Yenduri } 8972ec7cc7fSKrishna Yenduri 8982ec7cc7fSKrishna Yenduri static void 8992ec7cc7fSKrishna Yenduri kssl_lookup_sid(sslSessionID *sid, uchar_t *s, in6_addr_t *faddr, 9002ec7cc7fSKrishna Yenduri kssl_entry_t *kssl_entry) 9012ec7cc7fSKrishna Yenduri { 9022ec7cc7fSKrishna Yenduri uint_t index; 9032ec7cc7fSKrishna Yenduri kmutex_t *lock; 9042ec7cc7fSKrishna Yenduri sslSessionID *csid; 9052ec7cc7fSKrishna Yenduri 9062ec7cc7fSKrishna Yenduri KSSL_COUNTER(sid_cache_lookups, 1); 9072ec7cc7fSKrishna Yenduri 9082ec7cc7fSKrishna Yenduri SET_HASH_INDEX(index, s, faddr); 9092ec7cc7fSKrishna Yenduri index %= kssl_entry->sid_cache_nentries; 9102ec7cc7fSKrishna Yenduri 9112ec7cc7fSKrishna Yenduri lock = &(kssl_entry->sid_cache[index].se_lock); 9122ec7cc7fSKrishna Yenduri mutex_enter(lock); 9132ec7cc7fSKrishna Yenduri csid = &(kssl_entry->sid_cache[index].se_sid); 9142ec7cc7fSKrishna Yenduri if (csid->cached == B_FALSE || 9152ec7cc7fSKrishna Yenduri !IN6_ARE_ADDR_EQUAL(&csid->client_addr, faddr) || 916c28749e9Skais bcmp(csid->session_id, s, SSL3_SESSIONID_BYTES)) { 917c28749e9Skais mutex_exit(lock); 918c28749e9Skais return; 919c28749e9Skais } 920c28749e9Skais 921d3d50737SRafael Vanoni if (TICK_TO_SEC(ddi_get_lbolt() - csid->time) > 922d3d50737SRafael Vanoni kssl_entry->sid_cache_timeout) { 923c28749e9Skais csid->cached = B_FALSE; 924c28749e9Skais mutex_exit(lock); 925c28749e9Skais return; 926c28749e9Skais } 927c28749e9Skais 928c28749e9Skais bcopy(csid, sid, sizeof (*sid)); 929c28749e9Skais mutex_exit(lock); 930c28749e9Skais ASSERT(sid->cached == B_TRUE); 931c28749e9Skais 932c28749e9Skais KSSL_COUNTER(sid_cache_hits, 1); 933c28749e9Skais } 934c28749e9Skais 935c28749e9Skais static uchar_t * 936c28749e9Skais kssl_rsa_unwrap(uchar_t *buf, size_t *lenp) 937c28749e9Skais { 938c28749e9Skais size_t len = *lenp; 939c28749e9Skais int i = 2; 940c28749e9Skais 941c28749e9Skais if (buf[0] != 0 || buf[1] != 2) { 942c28749e9Skais return (NULL); 943c28749e9Skais } 944c28749e9Skais 945c28749e9Skais while (i < len) { 946c28749e9Skais if (buf[i++] == 0) { 947c28749e9Skais *lenp = len - i; 948c28749e9Skais break; 949c28749e9Skais } 950c28749e9Skais } 951c28749e9Skais 952c28749e9Skais if (i == len) { 953c28749e9Skais return (NULL); 954c28749e9Skais } 955c28749e9Skais 956c28749e9Skais return (buf + i); 957c28749e9Skais } 958c28749e9Skais 959c28749e9Skais 960c28749e9Skais #define KSSL_SSL3_SH_RECLEN (74) 961c28749e9Skais #define KSSL_SSL3_FIN_MSGLEN (36) 96211d0a659SVladimir Kotal #define KSSL_EMPTY_RENEG_INFO_LEN (7) 963c28749e9Skais 964c28749e9Skais #define KSSL_SSL3_MAX_CCP_FIN_MSGLEN (128) /* comfortable upper bound */ 965c28749e9Skais 96611d0a659SVladimir Kotal /* 96711d0a659SVladimir Kotal * Send ServerHello record to the client. 96811d0a659SVladimir Kotal */ 969c28749e9Skais static int 970c28749e9Skais kssl_send_server_hello(ssl_t *ssl) 971c28749e9Skais { 972c28749e9Skais mblk_t *mp; 973c28749e9Skais uchar_t *buf; 974c28749e9Skais uchar_t *msgstart; 97511d0a659SVladimir Kotal uint16_t reclen = KSSL_SSL3_SH_RECLEN; 976c28749e9Skais 977c28749e9Skais mp = allocb(ssl->tcp_mss, BPRI_HI); 978c28749e9Skais if (mp == NULL) { 979c28749e9Skais KSSL_COUNTER(alloc_fails, 1); 980c28749e9Skais return (ENOMEM); 981c28749e9Skais } 982c28749e9Skais ssl->handshake_sendbuf = mp; 983c28749e9Skais buf = mp->b_wptr; 984c28749e9Skais 98511d0a659SVladimir Kotal if (ssl->secure_renegotiation) 98611d0a659SVladimir Kotal reclen += KSSL_EMPTY_RENEG_INFO_LEN; 98711d0a659SVladimir Kotal 988c28749e9Skais /* 5 byte record header */ 989c28749e9Skais buf[0] = content_handshake; 990c28749e9Skais buf[1] = ssl->major_version; 991c28749e9Skais buf[2] = ssl->minor_version; 99211d0a659SVladimir Kotal buf[3] = reclen >> 8; 99311d0a659SVladimir Kotal buf[4] = reclen & 0xff; 994c28749e9Skais buf += SSL3_HDR_LEN; 995c28749e9Skais 996c28749e9Skais msgstart = buf; 997c28749e9Skais 998c28749e9Skais /* 6 byte message header */ 999c28749e9Skais buf[0] = (uchar_t)server_hello; /* message type */ 1000c28749e9Skais buf[1] = 0; /* message len byte 0 */ 100111d0a659SVladimir Kotal buf[2] = ((reclen - 4) >> 8) & 1002c28749e9Skais 0xff; /* message len byte 1 */ 100311d0a659SVladimir Kotal buf[3] = (reclen - 4) & 0xff; /* message len byte 2 */ 1004c28749e9Skais 1005c28749e9Skais buf[4] = ssl->major_version; /* version byte 0 */ 1006c28749e9Skais buf[5] = ssl->minor_version; /* version byte 1 */ 1007c28749e9Skais 1008c28749e9Skais buf += 6; 1009c28749e9Skais 1010c28749e9Skais kssl_get_hello_random(ssl->server_random); 1011c28749e9Skais bcopy(ssl->server_random, buf, SSL3_RANDOM_LENGTH); 1012c28749e9Skais buf += SSL3_RANDOM_LENGTH; 1013c28749e9Skais 1014c28749e9Skais buf[0] = SSL3_SESSIONID_BYTES; 1015c28749e9Skais bcopy(ssl->sid.session_id, buf + 1, SSL3_SESSIONID_BYTES); 1016c28749e9Skais buf += SSL3_SESSIONID_BYTES + 1; 1017c28749e9Skais 1018c28749e9Skais buf[0] = (ssl->pending_cipher_suite >> 8) & 0xff; 1019c28749e9Skais buf[1] = ssl->pending_cipher_suite & 0xff; 1020c28749e9Skais 1021c28749e9Skais buf[2] = 0; /* No compression */ 102211d0a659SVladimir Kotal buf += 3; 1023c28749e9Skais 102411d0a659SVladimir Kotal /* 102511d0a659SVladimir Kotal * Add "renegotiation_info" extension if the ClientHello message 102611d0a659SVladimir Kotal * contained either SCSV value in cipher suite list or 102711d0a659SVladimir Kotal * "renegotiation_info" extension. This is per RFC 5746, section 3.6. 102811d0a659SVladimir Kotal */ 102911d0a659SVladimir Kotal if (ssl->secure_renegotiation) { 103011d0a659SVladimir Kotal /* Extensions length */ 103111d0a659SVladimir Kotal buf[0] = 0x00; 103211d0a659SVladimir Kotal buf[1] = 0x05; 103311d0a659SVladimir Kotal /* empty renegotiation_info extension encoding (section 3.2) */ 103411d0a659SVladimir Kotal buf[2] = 0xff; 103511d0a659SVladimir Kotal buf[3] = 0x01; 103611d0a659SVladimir Kotal buf[4] = 0x00; 103711d0a659SVladimir Kotal buf[5] = 0x01; 103811d0a659SVladimir Kotal buf[6] = 0x00; 103911d0a659SVladimir Kotal buf += KSSL_EMPTY_RENEG_INFO_LEN; 104011d0a659SVladimir Kotal } 104111d0a659SVladimir Kotal 104211d0a659SVladimir Kotal mp->b_wptr = buf; 1043c28749e9Skais ASSERT(mp->b_wptr < mp->b_datap->db_lim); 1044c28749e9Skais 104511d0a659SVladimir Kotal kssl_update_handshake_hashes(ssl, msgstart, reclen); 1046c28749e9Skais return (0); 1047c28749e9Skais } 1048c28749e9Skais 1049c28749e9Skais static void 1050c28749e9Skais kssl_get_hello_random(uchar_t *buf) 1051c28749e9Skais { 1052c28749e9Skais timestruc_t ts; 1053c28749e9Skais time_t sec; 1054c28749e9Skais 1055c28749e9Skais gethrestime(&ts); 1056c28749e9Skais sec = ts.tv_sec; 1057c28749e9Skais 1058c28749e9Skais buf[0] = (sec >> 24) & 0xff; 1059c28749e9Skais buf[1] = (sec >> 16) & 0xff; 1060c28749e9Skais buf[2] = (sec >> 8) & 0xff; 1061c28749e9Skais buf[3] = (sec) & 0xff; 1062c28749e9Skais 1063c28749e9Skais (void) random_get_pseudo_bytes(&buf[4], SSL3_RANDOM_LENGTH - 4); 1064c28749e9Skais 1065c28749e9Skais /* Should this be caching? */ 1066c28749e9Skais } 1067c28749e9Skais 1068c28749e9Skais static int 1069c28749e9Skais kssl_tls_P_hash(crypto_mechanism_t *mech, crypto_key_t *key, 1070c28749e9Skais size_t hashlen, 1071c28749e9Skais uchar_t *label, size_t label_len, 1072c28749e9Skais uchar_t *seed, size_t seedlen, 1073c28749e9Skais uchar_t *data, size_t datalen) 1074c28749e9Skais { 1075c28749e9Skais int rv = 0; 1076c28749e9Skais uchar_t A1[MAX_HASH_LEN], result[MAX_HASH_LEN]; 1077dd49f125SAnders Persson int bytes_left = (int)datalen; 1078c28749e9Skais crypto_data_t dd, mac; 1079c28749e9Skais crypto_context_t ctx; 1080c28749e9Skais 1081c28749e9Skais dd.cd_format = CRYPTO_DATA_RAW; 1082c28749e9Skais dd.cd_offset = 0; 1083c28749e9Skais mac.cd_format = CRYPTO_DATA_RAW; 1084c28749e9Skais mac.cd_offset = 0; 1085c28749e9Skais 1086c28749e9Skais /* 10872ec7cc7fSKrishna Yenduri * A(i) = HMAC_hash(secret, seed + A(i-1)); 1088c28749e9Skais * A(0) = seed; 1089c28749e9Skais * 1090c28749e9Skais * Compute A(1): 1091c28749e9Skais * A(1) = HMAC_hash(secret, label + seed) 1092c28749e9Skais * 1093c28749e9Skais */ 1094c28749e9Skais HMAC_INIT(mech, key, &ctx); 1095c28749e9Skais HMAC_UPDATE(ctx, label, label_len); 1096c28749e9Skais HMAC_UPDATE(ctx, seed, seedlen); 1097c28749e9Skais HMAC_FINAL(ctx, A1, hashlen); 1098c28749e9Skais 1099c28749e9Skais /* Compute A(2) ... A(n) */ 1100c28749e9Skais while (bytes_left > 0) { 1101c28749e9Skais HMAC_INIT(mech, key, &ctx); 1102c28749e9Skais HMAC_UPDATE(ctx, A1, hashlen); 1103c28749e9Skais HMAC_UPDATE(ctx, label, label_len); 1104c28749e9Skais HMAC_UPDATE(ctx, seed, seedlen); 1105c28749e9Skais HMAC_FINAL(ctx, result, hashlen); 1106c28749e9Skais 1107c28749e9Skais /* 1108c28749e9Skais * The A(i) value is stored in "result". 1109c28749e9Skais * Save the results of the MAC so it can be input to next 1110c28749e9Skais * iteration. 1111c28749e9Skais */ 1112c28749e9Skais if (bytes_left > hashlen) { 1113c28749e9Skais /* Store the chunk result */ 1114c28749e9Skais bcopy(result, data, hashlen); 1115c28749e9Skais data += hashlen; 1116c28749e9Skais 1117c28749e9Skais bytes_left -= hashlen; 1118c28749e9Skais 1119c28749e9Skais /* Update A1 for next iteration */ 1120c28749e9Skais HMAC_INIT(mech, key, &ctx); 1121c28749e9Skais HMAC_UPDATE(ctx, A1, hashlen); 1122c28749e9Skais HMAC_FINAL(ctx, A1, hashlen); 1123c28749e9Skais 1124c28749e9Skais } else { 1125c28749e9Skais bcopy(result, data, bytes_left); 1126c28749e9Skais data += bytes_left; 1127c28749e9Skais bytes_left = 0; 1128c28749e9Skais } 1129c28749e9Skais } 1130c28749e9Skais end: 1131c28749e9Skais if (CRYPTO_ERR(rv)) { 113251dd2c77Svk199839 DTRACE_PROBE1(kssl_err__crypto_mac_error, int, rv); 1133c28749e9Skais KSSL_COUNTER(compute_mac_failure, 1); 1134c28749e9Skais } 1135c28749e9Skais return (rv); 1136c28749e9Skais } 1137c28749e9Skais 1138c28749e9Skais /* ARGSUSED */ 1139c28749e9Skais static int 1140c28749e9Skais kssl_tls_PRF(ssl_t *ssl, 1141c28749e9Skais uchar_t *secret, size_t secret_len, 1142c28749e9Skais uchar_t *label, size_t label_len, 1143c28749e9Skais uchar_t *seed, size_t seed_len, 1144c28749e9Skais uchar_t *prfresult, size_t prfresult_len) 1145c28749e9Skais { 1146c28749e9Skais /* 1147c28749e9Skais * RFC 2246: 1148c28749e9Skais * PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR 1149c28749e9Skais * P_SHA1(S2, label + seed); 1150c28749e9Skais * S1 = 1st half of secret. 1151c28749e9Skais * S1 = 2nd half of secret. 1152c28749e9Skais * 1153c28749e9Skais */ 1154c28749e9Skais 11552ec7cc7fSKrishna Yenduri int rv, i; 11562bd70d4bSkrishna uchar_t psha1[MAX_KEYBLOCK_LENGTH]; 1157c28749e9Skais crypto_key_t S1, S2; 1158c28749e9Skais 1159c28749e9Skais /* length of secret keys is ceil(length/2) */ 1160c28749e9Skais size_t slen = roundup(secret_len, 2) / 2; 1161c28749e9Skais 11622bd70d4bSkrishna if (prfresult_len > MAX_KEYBLOCK_LENGTH) { 116351dd2c77Svk199839 DTRACE_PROBE1(kssl_err__unexpected_keyblock_size, 116451dd2c77Svk199839 size_t, prfresult_len); 1165c28749e9Skais return (CRYPTO_ARGUMENTS_BAD); 1166c28749e9Skais } 1167c28749e9Skais 1168c28749e9Skais ASSERT(prfresult != NULL); 1169c28749e9Skais ASSERT(label != NULL); 1170c28749e9Skais ASSERT(seed != NULL); 1171c28749e9Skais 1172c28749e9Skais S1.ck_data = secret; 1173c28749e9Skais S1.ck_length = slen * 8; /* bits */ 1174c28749e9Skais S1.ck_format = CRYPTO_KEY_RAW; 1175c28749e9Skais 1176c28749e9Skais S2.ck_data = secret + slen; 1177c28749e9Skais S2.ck_length = slen * 8; /* bits */ 1178c28749e9Skais S2.ck_format = CRYPTO_KEY_RAW; 1179c28749e9Skais 1180c28749e9Skais rv = kssl_tls_P_hash(&hmac_md5_mech, &S1, MD5_HASH_LEN, 1181c28749e9Skais label, label_len, 1182c28749e9Skais seed, seed_len, 1183c28749e9Skais prfresult, prfresult_len); 1184c28749e9Skais if (CRYPTO_ERR(rv)) 1185c28749e9Skais goto end; 1186c28749e9Skais 1187c28749e9Skais rv = kssl_tls_P_hash(&hmac_sha1_mech, &S2, SHA1_HASH_LEN, 1188c28749e9Skais label, label_len, 1189c28749e9Skais seed, seed_len, 1190c28749e9Skais psha1, prfresult_len); 1191c28749e9Skais if (CRYPTO_ERR(rv)) 1192c28749e9Skais goto end; 1193c28749e9Skais 1194c28749e9Skais for (i = 0; i < prfresult_len; i++) 1195c28749e9Skais prfresult[i] ^= psha1[i]; 1196c28749e9Skais 1197c28749e9Skais end: 1198c28749e9Skais if (CRYPTO_ERR(rv)) 1199c28749e9Skais bzero(prfresult, prfresult_len); 1200c28749e9Skais 1201c28749e9Skais return (rv); 1202c28749e9Skais } 1203c28749e9Skais 1204968d6ddeSkrishna #define IS_BAD_PRE_MASTER_SECRET(pms, pmslen, ssl) \ 1205968d6ddeSkrishna (pms == NULL || pmslen != SSL3_PRE_MASTER_SECRET_LEN || \ 1206968d6ddeSkrishna pms[0] != ssl->major_version || pms[1] != ssl->minor_version) 1207968d6ddeSkrishna 1208968d6ddeSkrishna #define FAKE_PRE_MASTER_SECRET(pms, pmslen, ssl, buf) { \ 1209968d6ddeSkrishna KSSL_COUNTER(bad_pre_master_secret, 1); \ 1210968d6ddeSkrishna pms = buf; \ 1211968d6ddeSkrishna pmslen = SSL3_PRE_MASTER_SECRET_LEN; \ 1212968d6ddeSkrishna pms[0] = ssl->major_version; \ 1213968d6ddeSkrishna pms[1] = ssl->minor_version; \ 1214968d6ddeSkrishna (void) random_get_pseudo_bytes(&buf[2], pmslen - 2); \ 1215968d6ddeSkrishna } 1216968d6ddeSkrishna 1217c28749e9Skais static int 1218c28749e9Skais kssl_generate_tls_ms(ssl_t *ssl, uchar_t *pms, size_t pmslen) 1219c28749e9Skais { 1220968d6ddeSkrishna uchar_t buf[SSL3_PRE_MASTER_SECRET_LEN]; 1221c28749e9Skais uchar_t seed[SSL3_RANDOM_LENGTH * 2]; 1222c28749e9Skais 1223c28749e9Skais /* 1224c28749e9Skais * Computing the master secret: 1225c28749e9Skais * ---------------------------- 1226c28749e9Skais * master_secret = PRF (pms, "master secret", 1227c28749e9Skais * ClientHello.random + ServerHello.random); 1228c28749e9Skais */ 1229c28749e9Skais bcopy(ssl->client_random, seed, SSL3_RANDOM_LENGTH); 1230c28749e9Skais bcopy(ssl->server_random, seed + SSL3_RANDOM_LENGTH, 1231c28749e9Skais SSL3_RANDOM_LENGTH); 1232c28749e9Skais 1233968d6ddeSkrishna /* if pms is bad fake it to thwart Bleichenbacher attack */ 1234968d6ddeSkrishna if (IS_BAD_PRE_MASTER_SECRET(pms, pmslen, ssl)) { 123551dd2c77Svk199839 DTRACE_PROBE(kssl_err__under_Bleichenbacher_attack); 1236968d6ddeSkrishna FAKE_PRE_MASTER_SECRET(pms, pmslen, ssl, buf); 1237968d6ddeSkrishna } 1238968d6ddeSkrishna 1239c28749e9Skais return (kssl_tls_PRF(ssl, 1240c28749e9Skais pms, pmslen, 1241c28749e9Skais (uchar_t *)TLS_MASTER_SECRET_LABEL, 1242c28749e9Skais (size_t)strlen(TLS_MASTER_SECRET_LABEL), 1243c28749e9Skais seed, sizeof (seed), 1244c28749e9Skais ssl->sid.master_secret, 1245c28749e9Skais (size_t)sizeof (ssl->sid.master_secret))); 1246c28749e9Skais } 1247c28749e9Skais 1248968d6ddeSkrishna 1249c28749e9Skais static void 1250c28749e9Skais kssl_generate_ssl_ms(ssl_t *ssl, uchar_t *pms, size_t pmslen) 1251c28749e9Skais { 1252c28749e9Skais uchar_t buf[SSL3_PRE_MASTER_SECRET_LEN]; 1253c28749e9Skais uchar_t *ms; 1254c28749e9Skais int hlen = MD5_HASH_LEN; 1255c28749e9Skais 1256c28749e9Skais ms = ssl->sid.master_secret; 1257c28749e9Skais 1258c28749e9Skais /* if pms is bad fake it to thwart Bleichenbacher attack */ 1259968d6ddeSkrishna if (IS_BAD_PRE_MASTER_SECRET(pms, pmslen, ssl)) { 126051dd2c77Svk199839 DTRACE_PROBE(kssl_err__under_Bleichenbacher_attack); 1261968d6ddeSkrishna FAKE_PRE_MASTER_SECRET(pms, pmslen, ssl, buf); 1262c28749e9Skais } 1263968d6ddeSkrishna 1264c28749e9Skais kssl_ssl3_key_material_derive_step(ssl, pms, pmslen, 1, ms, 0); 1265c28749e9Skais kssl_ssl3_key_material_derive_step(ssl, pms, pmslen, 2, ms + hlen, 0); 1266c28749e9Skais kssl_ssl3_key_material_derive_step(ssl, pms, pmslen, 3, ms + 2 * hlen, 1267c28749e9Skais 0); 1268c28749e9Skais } 1269c28749e9Skais 1270c28749e9Skais static int 1271c28749e9Skais kssl_generate_tls_keyblock(ssl_t *ssl) 1272c28749e9Skais { 1273c28749e9Skais uchar_t seed[2 * SSL3_RANDOM_LENGTH]; 1274c28749e9Skais 1275c28749e9Skais bcopy(ssl->server_random, seed, SSL3_RANDOM_LENGTH); 1276c28749e9Skais bcopy(ssl->client_random, seed + SSL3_RANDOM_LENGTH, 1277c28749e9Skais SSL3_RANDOM_LENGTH); 1278c28749e9Skais 1279c28749e9Skais return (kssl_tls_PRF(ssl, ssl->sid.master_secret, 1280c28749e9Skais (size_t)SSL3_MASTER_SECRET_LEN, 1281c28749e9Skais (uchar_t *)TLS_KEY_EXPANSION_LABEL, 1282c28749e9Skais (size_t)strlen(TLS_KEY_EXPANSION_LABEL), 1283c28749e9Skais seed, (size_t)sizeof (seed), 1284c28749e9Skais ssl->pending_keyblock, 1285c28749e9Skais (size_t)ssl->pending_keyblksz)); 1286c28749e9Skais 1287c28749e9Skais } 1288c28749e9Skais 1289c28749e9Skais static void 1290c28749e9Skais kssl_generate_keyblock(ssl_t *ssl) 1291c28749e9Skais { 1292c28749e9Skais uchar_t *ms; 1293c28749e9Skais size_t mslen = SSL3_MASTER_SECRET_LEN; 1294c28749e9Skais int hlen = MD5_HASH_LEN; 1295c28749e9Skais uchar_t *keys = ssl->pending_keyblock; 1296c28749e9Skais int steps = howmany(ssl->pending_keyblksz, hlen); 1297c28749e9Skais int i; 1298c28749e9Skais 1299c28749e9Skais ms = ssl->sid.master_secret; 1300c28749e9Skais 1301c28749e9Skais ASSERT(hlen * steps <= MAX_KEYBLOCK_LENGTH); 1302c28749e9Skais 1303c28749e9Skais for (i = 1; i <= steps; i++) { 1304c28749e9Skais kssl_ssl3_key_material_derive_step(ssl, ms, mslen, i, keys, 1); 1305c28749e9Skais keys += hlen; 1306c28749e9Skais } 1307c28749e9Skais } 1308c28749e9Skais 13092bd70d4bSkrishna static char *ssl3_key_derive_seeds[9] = {"A", "BB", "CCC", "DDDD", "EEEEE", 13102bd70d4bSkrishna "FFFFFF", "GGGGGGG", "HHHHHHHH", "IIIIIIIII"}; 1311c28749e9Skais 1312c28749e9Skais static void 1313c28749e9Skais kssl_ssl3_key_material_derive_step( 1314c28749e9Skais ssl_t *ssl, 1315c28749e9Skais uchar_t *secret, 1316c28749e9Skais size_t secretlen, 1317c28749e9Skais int step, 1318c28749e9Skais uchar_t *dst, 1319c28749e9Skais int sr_first) 1320c28749e9Skais { 1321c28749e9Skais SHA1_CTX sha1, *sha1ctx; 1322c28749e9Skais MD5_CTX md5, *md5ctx; 1323c28749e9Skais uchar_t sha1_hash[SHA1_HASH_LEN]; 1324c28749e9Skais 1325c28749e9Skais sha1ctx = &sha1; 1326c28749e9Skais md5ctx = &md5; 1327c28749e9Skais 1328c28749e9Skais ASSERT(step <= 1329c28749e9Skais sizeof (ssl3_key_derive_seeds) / 1330c28749e9Skais sizeof (ssl3_key_derive_seeds[0])); 1331c28749e9Skais step--; 1332c28749e9Skais 1333c28749e9Skais SHA1Init(sha1ctx); 1334c28749e9Skais SHA1Update(sha1ctx, (uchar_t *)ssl3_key_derive_seeds[step], 1335c28749e9Skais step + 1); 1336c28749e9Skais SHA1Update(sha1ctx, secret, secretlen); 1337c28749e9Skais if (sr_first) { 1338c28749e9Skais SHA1Update(sha1ctx, ssl->server_random, SSL3_RANDOM_LENGTH); 1339c28749e9Skais SHA1Update(sha1ctx, ssl->client_random, SSL3_RANDOM_LENGTH); 1340c28749e9Skais } else { 1341c28749e9Skais SHA1Update(sha1ctx, ssl->client_random, SSL3_RANDOM_LENGTH); 1342c28749e9Skais SHA1Update(sha1ctx, ssl->server_random, SSL3_RANDOM_LENGTH); 1343c28749e9Skais } 1344c28749e9Skais SHA1Final(sha1_hash, sha1ctx); 1345c28749e9Skais 1346c28749e9Skais MD5Init(md5ctx); 1347c28749e9Skais MD5Update(md5ctx, secret, secretlen); 1348c28749e9Skais MD5Update(md5ctx, sha1_hash, SHA1_HASH_LEN); 1349c28749e9Skais MD5Final(dst, md5ctx); 1350c28749e9Skais } 1351c28749e9Skais 1352c28749e9Skais static int 1353c28749e9Skais kssl_send_certificate_and_server_hello_done(ssl_t *ssl) 1354c28749e9Skais { 1355c28749e9Skais int cur_reclen; 1356c28749e9Skais int mss; 1357c28749e9Skais int len, copylen; 1358c28749e9Skais mblk_t *mp; 1359c28749e9Skais uchar_t *cert_buf; 1360c28749e9Skais int cert_len; 1361c28749e9Skais uchar_t *msgbuf; 1362c28749e9Skais Certificate_t *cert; 136311d0a659SVladimir Kotal uint16_t reclen = KSSL_SSL3_SH_RECLEN; 1364c28749e9Skais 1365c28749e9Skais cert = ssl->kssl_entry->ke_server_certificate; 1366c28749e9Skais if (cert == NULL) { 1367c28749e9Skais return (ENOENT); 1368c28749e9Skais } 1369c28749e9Skais cert_buf = cert->msg; 1370c28749e9Skais cert_len = cert->len; 1371c28749e9Skais 137211d0a659SVladimir Kotal if (ssl->secure_renegotiation) 137311d0a659SVladimir Kotal reclen += KSSL_EMPTY_RENEG_INFO_LEN; 137411d0a659SVladimir Kotal 1375c28749e9Skais mp = ssl->handshake_sendbuf; 1376c28749e9Skais mss = ssl->tcp_mss; 1377c28749e9Skais ASSERT(mp != NULL); 1378c28749e9Skais cur_reclen = mp->b_wptr - mp->b_rptr - SSL3_HDR_LEN; 137911d0a659SVladimir Kotal ASSERT(cur_reclen == reclen); 1380c28749e9Skais /* Assume MSS is at least 80 bytes */ 1381c28749e9Skais ASSERT(mss > cur_reclen + SSL3_HDR_LEN); 1382c28749e9Skais ASSERT(cur_reclen < SSL3_MAX_RECORD_LENGTH); /* XXX */ 1383c28749e9Skais 1384c28749e9Skais copylen = mss - (cur_reclen + SSL3_HDR_LEN); 1385c28749e9Skais len = cert_len; 1386c28749e9Skais copylen = MIN(copylen, len); 1387c28749e9Skais copylen = MIN(copylen, SSL3_MAX_RECORD_LENGTH - cur_reclen); 1388c28749e9Skais 1389c28749e9Skais /* new record always starts in a new mblk for simplicity */ 1390c28749e9Skais msgbuf = cert_buf; 1391c28749e9Skais for (;;) { 1392c28749e9Skais ASSERT(mp->b_wptr + copylen <= mp->b_datap->db_lim); 1393c28749e9Skais bcopy(msgbuf, mp->b_wptr, copylen); 1394c28749e9Skais msgbuf += copylen; 1395c28749e9Skais mp->b_wptr += copylen; 1396c28749e9Skais cur_reclen += copylen; 1397c28749e9Skais len -= copylen; 1398c28749e9Skais if (len == 0) { 1399c28749e9Skais break; 1400c28749e9Skais } 1401c28749e9Skais if (cur_reclen == SSL3_MAX_RECORD_LENGTH) { 1402c28749e9Skais cur_reclen = 0; 1403c28749e9Skais } 1404c28749e9Skais copylen = MIN(len, mss); 1405c28749e9Skais copylen = MIN(copylen, SSL3_MAX_RECORD_LENGTH - cur_reclen); 1406c28749e9Skais mp->b_cont = allocb(copylen, BPRI_HI); 1407c28749e9Skais if (mp->b_cont == NULL) { 1408c28749e9Skais KSSL_COUNTER(alloc_fails, 1); 1409c28749e9Skais freemsg(ssl->handshake_sendbuf); 1410c28749e9Skais ssl->handshake_sendbuf = NULL; 1411c28749e9Skais return (ENOMEM); 1412c28749e9Skais } 1413c28749e9Skais mp = mp->b_cont; 1414c28749e9Skais if (cur_reclen == 0) { 1415c28749e9Skais mp->b_wptr[0] = content_handshake; 1416c28749e9Skais mp->b_wptr[1] = ssl->major_version; 1417c28749e9Skais mp->b_wptr[2] = ssl->minor_version; 141811d0a659SVladimir Kotal cur_reclen = MIN(len, reclen); 1419c28749e9Skais mp->b_wptr[3] = (cur_reclen >> 8) & 0xff; 1420c28749e9Skais mp->b_wptr[4] = (cur_reclen) & 0xff; 1421c28749e9Skais mp->b_wptr += SSL3_HDR_LEN; 1422c28749e9Skais cur_reclen = 0; 1423c28749e9Skais copylen = MIN(copylen, mss - SSL3_HDR_LEN); 1424c28749e9Skais } 1425c28749e9Skais } 1426c28749e9Skais 1427c28749e9Skais /* adjust the record length field for the first record */ 1428c28749e9Skais mp = ssl->handshake_sendbuf; 142911d0a659SVladimir Kotal cur_reclen = MIN(reclen + cert_len, SSL3_MAX_RECORD_LENGTH); 1430c28749e9Skais mp->b_rptr[3] = (cur_reclen >> 8) & 0xff; 1431c28749e9Skais mp->b_rptr[4] = (cur_reclen) & 0xff; 1432c28749e9Skais 1433c28749e9Skais kssl_update_handshake_hashes(ssl, cert_buf, cert_len); 1434c28749e9Skais 1435c28749e9Skais return (0); 1436c28749e9Skais } 1437c28749e9Skais 1438c28749e9Skais static int 1439c28749e9Skais kssl_send_change_cipher_specs(ssl_t *ssl) 1440c28749e9Skais { 1441c28749e9Skais mblk_t *mp, *newmp; 1442c28749e9Skais uchar_t *buf; 1443c28749e9Skais 1444c28749e9Skais mp = ssl->handshake_sendbuf; 1445c28749e9Skais 1446c28749e9Skais /* We're most likely to hit the fast path for resumed sessions */ 1447c28749e9Skais if ((mp != NULL) && 1448c28749e9Skais (mp->b_datap->db_lim - mp->b_wptr > KSSL_SSL3_MAX_CCP_FIN_MSGLEN)) { 1449c28749e9Skais buf = mp->b_wptr; 1450c28749e9Skais } else { 1451c28749e9Skais newmp = allocb(KSSL_SSL3_MAX_CCP_FIN_MSGLEN, BPRI_HI); 1452c28749e9Skais 1453c28749e9Skais if (newmp == NULL) 1454c28749e9Skais return (ENOMEM); /* need to do better job! */ 1455c28749e9Skais 1456c28749e9Skais if (mp == NULL) { 1457c28749e9Skais ssl->handshake_sendbuf = newmp; 1458c28749e9Skais } else { 1459c28749e9Skais linkb(ssl->handshake_sendbuf, newmp); 1460c28749e9Skais } 1461c28749e9Skais mp = newmp; 1462c28749e9Skais buf = mp->b_rptr; 1463c28749e9Skais } 1464c28749e9Skais 1465c28749e9Skais /* 5 byte record header */ 1466c28749e9Skais buf[0] = content_change_cipher_spec; 1467c28749e9Skais buf[1] = ssl->major_version; 1468c28749e9Skais buf[2] = ssl->minor_version; 1469c28749e9Skais buf[3] = 0; 1470c28749e9Skais buf[4] = 1; 1471c28749e9Skais buf += SSL3_HDR_LEN; 1472c28749e9Skais 1473c28749e9Skais buf[0] = 1; 1474c28749e9Skais 1475c28749e9Skais mp->b_wptr = buf + 1; 1476c28749e9Skais ASSERT(mp->b_wptr < mp->b_datap->db_lim); 1477c28749e9Skais 1478c28749e9Skais ssl->seq_num[KSSL_WRITE] = 0; 1479c28749e9Skais return (kssl_spec_init(ssl, KSSL_WRITE)); 1480c28749e9Skais } 1481c28749e9Skais 1482c28749e9Skais int 1483c28749e9Skais kssl_spec_init(ssl_t *ssl, int dir) 1484c28749e9Skais { 1485c28749e9Skais KSSL_HASHCTX *ctx; 1486c28749e9Skais KSSLCipherSpec *spec = &ssl->spec[dir]; 1487c28749e9Skais int ret = 0; 1488c28749e9Skais 1489c28749e9Skais spec->mac_hashsz = mac_defs[ssl->pending_malg].hashsz; 1490c28749e9Skais spec->mac_padsz = mac_defs[ssl->pending_malg].padsz; 1491c28749e9Skais 1492c28749e9Skais spec->MAC_HashInit = mac_defs[ssl->pending_malg].HashInit; 1493c28749e9Skais spec->MAC_HashUpdate = mac_defs[ssl->pending_malg].HashUpdate; 1494c28749e9Skais spec->MAC_HashFinal = mac_defs[ssl->pending_malg].HashFinal; 1495c28749e9Skais 1496c28749e9Skais if (dir == KSSL_READ) { 1497c28749e9Skais bcopy(ssl->pending_keyblock, ssl->mac_secret[dir], 1498c28749e9Skais spec->mac_hashsz); 1499c28749e9Skais } else { 1500c28749e9Skais bcopy(&(ssl->pending_keyblock[spec->mac_hashsz]), 1501c28749e9Skais ssl->mac_secret[dir], spec->mac_hashsz); 1502c28749e9Skais } 1503c28749e9Skais 1504c28749e9Skais /* Pre-compute these here. will save cycles on each record later */ 1505c28749e9Skais if (!IS_TLS(ssl)) { 1506c28749e9Skais ctx = &ssl->mac_ctx[dir][0]; 1507c28749e9Skais spec->MAC_HashInit((void *)ctx); 1508c28749e9Skais spec->MAC_HashUpdate((void *)ctx, ssl->mac_secret[dir], 1509c28749e9Skais spec->mac_hashsz); 1510c28749e9Skais spec->MAC_HashUpdate((void *)ctx, kssl_pad_1, 1511c28749e9Skais spec->mac_padsz); 1512c28749e9Skais 1513c28749e9Skais ctx = &ssl->mac_ctx[dir][1]; 1514c28749e9Skais spec->MAC_HashInit((void *)ctx); 1515c28749e9Skais spec->MAC_HashUpdate((void *)ctx, ssl->mac_secret[dir], 1516c28749e9Skais spec->mac_hashsz); 1517c28749e9Skais spec->MAC_HashUpdate((void *)ctx, kssl_pad_2, 1518c28749e9Skais spec->mac_padsz); 1519c28749e9Skais } 1520c28749e9Skais 1521c28749e9Skais spec->cipher_type = cipher_defs[ssl->pending_calg].type; 1522c28749e9Skais spec->cipher_mech.cm_type = cipher_defs[ssl->pending_calg].mech_type; 1523c28749e9Skais spec->cipher_bsize = cipher_defs[ssl->pending_calg].bsize; 1524c28749e9Skais spec->cipher_keysz = cipher_defs[ssl->pending_calg].keysz; 1525c28749e9Skais 1526c28749e9Skais if (spec->cipher_ctx != NULL) { 1527c28749e9Skais crypto_cancel_ctx(spec->cipher_ctx); 1528c28749e9Skais spec->cipher_ctx = 0; 1529c28749e9Skais } 1530c28749e9Skais 1531c28749e9Skais /* 1532efe05f9eSkrishna * Initialize HMAC keys for TLS and SSL3 HMAC keys 1533efe05f9eSkrishna * for SSL 3.0. 1534c28749e9Skais */ 1535c28749e9Skais if (IS_TLS(ssl)) { 1536c28749e9Skais if (ssl->pending_malg == mac_md5) { 1537c28749e9Skais spec->hmac_mech = hmac_md5_mech; 1538c28749e9Skais } else if (ssl->pending_malg == mac_sha) { 1539c28749e9Skais spec->hmac_mech = hmac_sha1_mech; 1540c28749e9Skais } 1541c28749e9Skais 1542c28749e9Skais spec->hmac_key.ck_format = CRYPTO_KEY_RAW; 1543c28749e9Skais spec->hmac_key.ck_data = ssl->mac_secret[dir]; 1544c28749e9Skais spec->hmac_key.ck_length = spec->mac_hashsz * 8; 1545efe05f9eSkrishna } else { 1546efe05f9eSkrishna static uint32_t param; 1547efe05f9eSkrishna 1548efe05f9eSkrishna spec->hmac_mech.cm_type = CRYPTO_MECH_INVALID; 1549efe05f9eSkrishna spec->hmac_mech.cm_param = (caddr_t)¶m; 1550efe05f9eSkrishna spec->hmac_mech.cm_param_len = sizeof (param); 1551efe05f9eSkrishna if (ssl->pending_malg == mac_md5) { 1552efe05f9eSkrishna spec->hmac_mech.cm_type = 1553efe05f9eSkrishna crypto_mech2id("CKM_SSL3_MD5_MAC"); 1554efe05f9eSkrishna param = MD5_HASH_LEN; 1555efe05f9eSkrishna } else if (ssl->pending_malg == mac_sha) { 1556efe05f9eSkrishna spec->hmac_mech.cm_type = 1557efe05f9eSkrishna crypto_mech2id("CKM_SSL3_SHA1_MAC"); 1558efe05f9eSkrishna param = SHA1_HASH_LEN; 1559efe05f9eSkrishna } 1560efe05f9eSkrishna 1561efe05f9eSkrishna spec->hmac_key.ck_format = CRYPTO_KEY_RAW; 1562efe05f9eSkrishna spec->hmac_key.ck_data = ssl->mac_secret[dir]; 1563efe05f9eSkrishna spec->hmac_key.ck_length = spec->mac_hashsz * 8; 1564c28749e9Skais } 1565c28749e9Skais 1566c28749e9Skais /* We're done if this is the nil cipher */ 1567c28749e9Skais if (spec->cipher_keysz == 0) { 1568c28749e9Skais return (0); 1569c28749e9Skais } 1570c28749e9Skais 1571c28749e9Skais /* Initialize the key and the active context */ 1572c28749e9Skais spec->cipher_key.ck_format = CRYPTO_KEY_RAW; 1573c28749e9Skais spec->cipher_key.ck_length = 8 * spec->cipher_keysz; /* in bits */ 1574c28749e9Skais 1575c28749e9Skais if (cipher_defs[ssl->pending_calg].bsize > 0) { 1576c28749e9Skais /* client_write_IV */ 1577c28749e9Skais spec->cipher_mech.cm_param = 1578c28749e9Skais (caddr_t)&(ssl->pending_keyblock[2 * spec->mac_hashsz + 1579c28749e9Skais 2 * spec->cipher_keysz]); 1580c28749e9Skais spec->cipher_mech.cm_param_len = spec->cipher_bsize; 1581c28749e9Skais } 1582c28749e9Skais spec->cipher_data.cd_format = CRYPTO_DATA_RAW; 1583c28749e9Skais if (dir == KSSL_READ) { 1584c28749e9Skais spec->cipher_mech.cm_param_len = 1585c28749e9Skais cipher_defs[ssl->pending_calg].bsize; 1586c28749e9Skais 1587c892ebf1Skrishna /* client_write_key */ 1588c28749e9Skais spec->cipher_key.ck_data = 1589c28749e9Skais &(ssl->pending_keyblock[2 * spec->mac_hashsz]); 1590c28749e9Skais 1591c28749e9Skais ret = crypto_decrypt_init(&(spec->cipher_mech), 1592c28749e9Skais &(spec->cipher_key), NULL, &spec->cipher_ctx, NULL); 1593c28749e9Skais if (CRYPTO_ERR(ret)) { 159451dd2c77Svk199839 DTRACE_PROBE1(kssl_err__crypto_decrypt_init_read, 159551dd2c77Svk199839 int, ret); 1596c28749e9Skais } 1597c28749e9Skais } else { 1598c28749e9Skais if (cipher_defs[ssl->pending_calg].bsize > 0) { 159951144063SKrishna Yenduri /* server_write_IV */ 1600c28749e9Skais spec->cipher_mech.cm_param += spec->cipher_bsize; 1601c28749e9Skais } 160251144063SKrishna Yenduri 1603c28749e9Skais /* server_write_key */ 1604c28749e9Skais spec->cipher_key.ck_data = 1605c28749e9Skais &(ssl->pending_keyblock[2 * spec->mac_hashsz + 1606c28749e9Skais spec->cipher_keysz]); 1607c28749e9Skais 1608c28749e9Skais ret = crypto_encrypt_init(&(spec->cipher_mech), 1609c28749e9Skais &(spec->cipher_key), NULL, &spec->cipher_ctx, NULL); 1610c28749e9Skais if (CRYPTO_ERR(ret)) 161151dd2c77Svk199839 DTRACE_PROBE1(kssl_err__crypto_encrypt_init_non_read, 161251dd2c77Svk199839 int, ret); 1613c28749e9Skais } 1614c28749e9Skais return (ret); 1615c28749e9Skais } 1616c28749e9Skais 1617c28749e9Skais static int 1618c28749e9Skais kssl_send_finished(ssl_t *ssl, int update_hsh) 1619c28749e9Skais { 1620c28749e9Skais mblk_t *mp; 1621c28749e9Skais uchar_t *buf; 1622c28749e9Skais uchar_t *rstart; 1623c28749e9Skais uchar_t *versionp; 1624c28749e9Skais SSL3Hashes ssl3hashes; 1625dd49f125SAnders Persson uchar_t finish_len; 16262ec7cc7fSKrishna Yenduri int ret; 162711d0a659SVladimir Kotal uint16_t adj_len = 0; 1628c28749e9Skais 1629c28749e9Skais mp = ssl->handshake_sendbuf; 1630c28749e9Skais ASSERT(mp != NULL); 1631c28749e9Skais buf = mp->b_wptr; 163211d0a659SVladimir Kotal if (ssl->secure_renegotiation) 163311d0a659SVladimir Kotal adj_len = KSSL_EMPTY_RENEG_INFO_LEN; 163411d0a659SVladimir Kotal /* 163511d0a659SVladimir Kotal * It should be either a message with Server Hello record or just plain 163611d0a659SVladimir Kotal * SSL header (data packet). 163711d0a659SVladimir Kotal */ 163811d0a659SVladimir Kotal ASSERT(buf - mp->b_rptr == 163911d0a659SVladimir Kotal SSL3_HDR_LEN + KSSL_SSL3_SH_RECLEN + SSL3_HDR_LEN + 1 + adj_len || 164011d0a659SVladimir Kotal buf - mp->b_rptr == SSL3_HDR_LEN + 1); 1641c28749e9Skais 1642c28749e9Skais rstart = buf; 1643c28749e9Skais 1644c28749e9Skais if (IS_TLS(ssl)) 1645c28749e9Skais finish_len = TLS_FINISHED_SIZE; 1646c28749e9Skais else 1647c28749e9Skais finish_len = KSSL_SSL3_FIN_MSGLEN; 1648c28749e9Skais 1649c28749e9Skais /* 5 byte record header */ 1650c28749e9Skais buf[0] = content_handshake; 1651c28749e9Skais buf[1] = ssl->major_version; 1652c28749e9Skais buf[2] = ssl->minor_version; 1653c28749e9Skais buf[3] = 0; 1654c28749e9Skais buf[4] = 4 + finish_len; 1655c28749e9Skais 1656c28749e9Skais versionp = &buf[1]; 1657c28749e9Skais 1658c28749e9Skais buf += SSL3_HDR_LEN; 1659c28749e9Skais 1660c28749e9Skais /* 4 byte message header */ 1661c28749e9Skais buf[0] = (uchar_t)finished; /* message type */ 1662c28749e9Skais buf[1] = 0; /* message len byte 0 */ 1663c28749e9Skais buf[2] = 0; /* message len byte 1 */ 1664c28749e9Skais buf[3] = finish_len; /* message len byte 2 */ 1665c28749e9Skais buf += 4; 1666c28749e9Skais 1667c28749e9Skais if (IS_TLS(ssl)) { 1668c28749e9Skais bcopy(ssl->hs_hashes.md5, ssl3hashes.md5, 1669c28749e9Skais sizeof (ssl3hashes.md5)); 1670c28749e9Skais bcopy(ssl->hs_hashes.sha1, ssl3hashes.sha1, 1671c28749e9Skais sizeof (ssl3hashes.sha1)); 1672c28749e9Skais } 1673c28749e9Skais 1674c28749e9Skais /* Compute hashes for the SENDER side */ 1675c28749e9Skais ret = kssl_compute_handshake_hashes(ssl, &ssl3hashes, sender_server); 1676c28749e9Skais if (ret != 0) 1677c28749e9Skais return (ret); 1678c28749e9Skais 1679c28749e9Skais if (IS_TLS(ssl)) { 1680c28749e9Skais bcopy(ssl3hashes.tlshash, buf, sizeof (ssl3hashes.tlshash)); 1681c28749e9Skais } else { 1682c28749e9Skais bcopy(ssl3hashes.md5, buf, MD5_HASH_LEN); 1683c28749e9Skais bcopy(ssl3hashes.sha1, buf + MD5_HASH_LEN, SHA1_HASH_LEN); 1684c28749e9Skais } 1685c28749e9Skais 1686c28749e9Skais if (update_hsh) { 1687c28749e9Skais kssl_update_handshake_hashes(ssl, buf - 4, finish_len + 4); 1688c28749e9Skais } 1689c28749e9Skais 1690c28749e9Skais mp->b_wptr = buf + finish_len; 1691c28749e9Skais 1692c28749e9Skais ret = kssl_mac_encrypt_record(ssl, content_handshake, versionp, 1693c28749e9Skais rstart, mp); 1694c28749e9Skais ASSERT(mp->b_wptr <= mp->b_datap->db_lim); 1695c28749e9Skais 1696c28749e9Skais return (ret); 1697c28749e9Skais } 1698c28749e9Skais 1699c28749e9Skais int 1700c28749e9Skais kssl_mac_encrypt_record(ssl_t *ssl, 1701c28749e9Skais SSL3ContentType ct, 1702c28749e9Skais uchar_t *versionp, 1703c28749e9Skais uchar_t *rstart, 1704c28749e9Skais mblk_t *mp) 1705c28749e9Skais { 1706c28749e9Skais KSSLCipherSpec *spec; 1707c28749e9Skais int mac_sz; 1708c28749e9Skais int ret = 0; 1709c28749e9Skais uint16_t rec_sz; 1710c28749e9Skais int pad_sz; 1711c28749e9Skais int i; 1712c28749e9Skais 1713c28749e9Skais ASSERT(ssl != NULL); 1714c28749e9Skais ASSERT(rstart >= mp->b_rptr); 1715c28749e9Skais ASSERT(rstart < mp->b_wptr); 1716c28749e9Skais 1717c28749e9Skais spec = &ssl->spec[KSSL_WRITE]; 1718c28749e9Skais mac_sz = spec->mac_hashsz; 1719c28749e9Skais 1720c28749e9Skais rec_sz = (mp->b_wptr - rstart) - SSL3_HDR_LEN; 1721c28749e9Skais ASSERT(rec_sz > 0); 1722c28749e9Skais 1723c28749e9Skais if (mac_sz != 0) { 1724c28749e9Skais ASSERT(mp->b_wptr + mac_sz <= mp->b_datap->db_lim); 1725c28749e9Skais ret = kssl_compute_record_mac(ssl, KSSL_WRITE, 1726c28749e9Skais ssl->seq_num[KSSL_WRITE], ct, versionp, 1727c28749e9Skais rstart + SSL3_HDR_LEN, rec_sz, mp->b_wptr); 1728c28749e9Skais if (ret == CRYPTO_SUCCESS) { 1729c28749e9Skais ssl->seq_num[KSSL_WRITE]++; 1730c28749e9Skais mp->b_wptr += mac_sz; 1731c28749e9Skais rec_sz += mac_sz; 1732c28749e9Skais } else { 1733c28749e9Skais return (ret); 1734c28749e9Skais } 1735c28749e9Skais } 1736c28749e9Skais 1737c28749e9Skais if (spec->cipher_type == type_block) { 1738c28749e9Skais pad_sz = spec->cipher_bsize - 1739c28749e9Skais (rec_sz & (spec->cipher_bsize - 1)); 1740c28749e9Skais ASSERT(mp->b_wptr + pad_sz <= mp->b_datap->db_lim); 1741c28749e9Skais for (i = 0; i < pad_sz; i++) { 1742c28749e9Skais mp->b_wptr[i] = pad_sz - 1; 1743c28749e9Skais } 1744c28749e9Skais mp->b_wptr += pad_sz; 1745c28749e9Skais rec_sz += pad_sz; 1746c28749e9Skais } 1747c28749e9Skais 1748c28749e9Skais ASSERT(rec_sz <= SSL3_MAX_RECORD_LENGTH); 1749c28749e9Skais 1750c28749e9Skais U16_TO_BE16(rec_sz, rstart + 3); 1751c28749e9Skais 1752c28749e9Skais if (spec->cipher_ctx == 0) 1753c28749e9Skais return (ret); 1754c28749e9Skais 1755c28749e9Skais spec->cipher_data.cd_length = rec_sz; 1756c28749e9Skais spec->cipher_data.cd_raw.iov_base = (char *)(rstart + SSL3_HDR_LEN); 1757c28749e9Skais spec->cipher_data.cd_raw.iov_len = rec_sz; 1758c28749e9Skais /* One record at a time. Otherwise, gotta allocate the crypt_data_t */ 1759c28749e9Skais ret = crypto_encrypt_update(spec->cipher_ctx, &spec->cipher_data, 1760c28749e9Skais NULL, NULL); 1761c28749e9Skais if (CRYPTO_ERR(ret)) { 176251dd2c77Svk199839 DTRACE_PROBE1(kssl_err__crypto_encrypt_update, 176351dd2c77Svk199839 int, ret); 1764c28749e9Skais } 1765c28749e9Skais return (ret); 1766c28749e9Skais } 1767c28749e9Skais 17687dd0d8ffSVladimir Kotal /* 17697dd0d8ffSVladimir Kotal * Produce SSL alert message (SSLv3/TLS) or error message (SSLv2). For SSLv2 17707dd0d8ffSVladimir Kotal * it is only done to tear down the SSL connection so it has fixed encoding. 17717dd0d8ffSVladimir Kotal */ 1772c28749e9Skais void 1773c28749e9Skais kssl_send_alert(ssl_t *ssl, SSL3AlertLevel level, SSL3AlertDescription desc) 1774c28749e9Skais { 1775c28749e9Skais mblk_t *mp; 1776c28749e9Skais uchar_t *buf; 1777c28749e9Skais KSSLCipherSpec *spec; 17787dd0d8ffSVladimir Kotal size_t len; 1779c28749e9Skais 1780c28749e9Skais ASSERT(ssl != NULL); 1781c28749e9Skais 1782c28749e9Skais ssl->sendalert_level = level; 1783c28749e9Skais ssl->sendalert_desc = desc; 1784c28749e9Skais 1785c28749e9Skais if (level == alert_fatal) { 178651dd2c77Svk199839 DTRACE_PROBE2(kssl_sending_alert, 178751dd2c77Svk199839 SSL3AlertLevel, level, SSL3AlertDescription, desc); 1788c28749e9Skais if (ssl->sid.cached == B_TRUE) { 1789c28749e9Skais kssl_uncache_sid(&ssl->sid, ssl->kssl_entry); 1790c28749e9Skais } 1791c28749e9Skais ssl->fatal_alert = B_TRUE; 1792c28749e9Skais KSSL_COUNTER(fatal_alerts, 1); 1793c28749e9Skais } else 1794c28749e9Skais KSSL_COUNTER(warning_alerts, 1); 1795c28749e9Skais 1796c28749e9Skais spec = &ssl->spec[KSSL_WRITE]; 1797c28749e9Skais 1798c28749e9Skais ASSERT(ssl->alert_sendbuf == NULL); 1799*9b1bd49fSVladimir Kotal if (ssl->major_version == 0x03) { 1800*9b1bd49fSVladimir Kotal len = SSL3_HDR_LEN + SSL3_ALERT_LEN; 1801*9b1bd49fSVladimir Kotal } else { 1802*9b1bd49fSVladimir Kotal /* KSSL generates 5 byte SSLv2 alert messages only. */ 18037dd0d8ffSVladimir Kotal len = 5; 1804*9b1bd49fSVladimir Kotal } 18057dd0d8ffSVladimir Kotal ssl->alert_sendbuf = mp = allocb(len + spec->mac_hashsz + 1806c28749e9Skais spec->cipher_bsize, BPRI_HI); 1807c28749e9Skais if (mp == NULL) { 1808c28749e9Skais KSSL_COUNTER(alloc_fails, 1); 1809c28749e9Skais return; 1810c28749e9Skais } 1811c28749e9Skais buf = mp->b_wptr; 1812c28749e9Skais 18137dd0d8ffSVladimir Kotal /* SSLv3/TLS */ 18147dd0d8ffSVladimir Kotal if (ssl->major_version == 0x03) { 1815c28749e9Skais /* 5 byte record header */ 1816c28749e9Skais buf[0] = content_alert; 1817c28749e9Skais buf[1] = ssl->major_version; 1818c28749e9Skais buf[2] = ssl->minor_version; 1819c28749e9Skais buf[3] = 0; 1820c28749e9Skais buf[4] = 2; 1821c28749e9Skais buf += SSL3_HDR_LEN; 1822c28749e9Skais 1823c28749e9Skais /* alert contents */ 1824c28749e9Skais buf[0] = (uchar_t)level; 1825c28749e9Skais buf[1] = (uchar_t)desc; 1826*9b1bd49fSVladimir Kotal buf += SSL3_ALERT_LEN; 18277dd0d8ffSVladimir Kotal } else { 18287dd0d8ffSVladimir Kotal /* SSLv2 has different encoding. */ 18297dd0d8ffSVladimir Kotal /* 2-byte encoding of the length */ 18307dd0d8ffSVladimir Kotal buf[0] = 0x80; 18317dd0d8ffSVladimir Kotal buf[1] = 0x03; 18327dd0d8ffSVladimir Kotal buf += 2; 1833c28749e9Skais 18347dd0d8ffSVladimir Kotal /* Protocol Message Code = Error */ 18357dd0d8ffSVladimir Kotal buf[0] = 0; 18367dd0d8ffSVladimir Kotal /* Error Message Code = Undefined Error */ 18377dd0d8ffSVladimir Kotal buf[1] = 0; 18387dd0d8ffSVladimir Kotal buf[2] = 0; 18397dd0d8ffSVladimir Kotal buf += 3; 18407dd0d8ffSVladimir Kotal } 18417dd0d8ffSVladimir Kotal 18427dd0d8ffSVladimir Kotal mp->b_wptr = buf; 1843c28749e9Skais } 1844c28749e9Skais 1845c28749e9Skais /* Assumes RSA encryption */ 1846c28749e9Skais static int 1847c28749e9Skais kssl_handle_client_key_exchange(ssl_t *ssl, mblk_t *mp, int msglen, 1848c28749e9Skais kssl_callback_t cbfn, void *arg) 1849c28749e9Skais { 1850c28749e9Skais char *buf; 1851c28749e9Skais uchar_t *pms; 1852c28749e9Skais size_t pmslen; 1853c28749e9Skais int allocated; 1854c892ebf1Skrishna int err, rverr = ENOMEM; 1855c892ebf1Skrishna kssl_entry_t *ep; 1856c28749e9Skais crypto_key_t *privkey; 1857c28749e9Skais crypto_data_t *wrapped_pms_data, *pms_data; 1858c28749e9Skais crypto_call_req_t creq, *creqp; 1859c28749e9Skais 1860c892ebf1Skrishna ep = ssl->kssl_entry; 1861c892ebf1Skrishna privkey = ep->ke_private_key; 1862c28749e9Skais if (privkey == NULL) { 1863c28749e9Skais return (ENOENT); 1864c28749e9Skais } 1865c28749e9Skais 1866c28749e9Skais ASSERT(ssl->msg.type == client_key_exchange); 1867c28749e9Skais ASSERT(ssl->hs_waitstate == wait_client_key); 1868c28749e9Skais 1869c28749e9Skais /* 1870c28749e9Skais * TLS adds an extra 2 byte length field before the data. 1871c28749e9Skais */ 1872c28749e9Skais if (IS_TLS(ssl)) { 1873c28749e9Skais msglen = (mp->b_rptr[0] << 8) | mp->b_rptr[1]; 1874c28749e9Skais mp->b_rptr += 2; 1875c28749e9Skais } 1876c28749e9Skais 1877c28749e9Skais /* 1878c28749e9Skais * Allocate all we need in one shot. about 300 bytes total, for 1879c28749e9Skais * 1024 bit RSA modulus. 1880c28749e9Skais * The buffer layout will be: pms_data, wrapped_pms_data, the 1881c28749e9Skais * value of the wrapped pms from the client, then room for the 1882c28749e9Skais * resulting decrypted premaster secret. 1883c28749e9Skais */ 1884c28749e9Skais allocated = 2 * (sizeof (crypto_data_t) + msglen); 1885c28749e9Skais buf = kmem_alloc(allocated, KM_NOSLEEP); 1886c28749e9Skais if (buf == NULL) { 1887c28749e9Skais return (ENOMEM); 1888c28749e9Skais } 1889c28749e9Skais 1890c28749e9Skais pms_data = (crypto_data_t *)buf; 1891c28749e9Skais wrapped_pms_data = &(((crypto_data_t *)buf)[1]); 1892c28749e9Skais 1893c28749e9Skais wrapped_pms_data->cd_format = pms_data->cd_format = CRYPTO_DATA_RAW; 1894c28749e9Skais wrapped_pms_data->cd_offset = pms_data->cd_offset = 0; 1895c28749e9Skais wrapped_pms_data->cd_length = pms_data->cd_length = msglen; 1896c28749e9Skais wrapped_pms_data->cd_miscdata = pms_data->cd_miscdata = NULL; 1897c28749e9Skais wrapped_pms_data->cd_raw.iov_len = pms_data->cd_raw.iov_len = msglen; 1898c28749e9Skais wrapped_pms_data->cd_raw.iov_base = buf + 2 * sizeof (crypto_data_t); 1899c28749e9Skais pms_data->cd_raw.iov_base = wrapped_pms_data->cd_raw.iov_base + msglen; 1900c28749e9Skais 1901c28749e9Skais bcopy(mp->b_rptr, wrapped_pms_data->cd_raw.iov_base, msglen); 1902c28749e9Skais mp->b_rptr += msglen; 1903c28749e9Skais 1904c28749e9Skais /* Proceed synchronously if out of interrupt and configured to do so */ 1905c28749e9Skais if ((kssl_synchronous) && (!servicing_interrupt())) { 1906c28749e9Skais creqp = NULL; 1907c28749e9Skais } else { 1908c28749e9Skais ssl->cke_callback_func = cbfn; 1909c28749e9Skais ssl->cke_callback_arg = arg; 1910c28749e9Skais creq.cr_flag = kssl_call_flag; 1911c28749e9Skais creq.cr_callback_func = kssl_cke_done; 1912c28749e9Skais creq.cr_callback_arg = ssl; 1913c28749e9Skais 1914c28749e9Skais creqp = &creq; 1915c28749e9Skais } 1916c28749e9Skais 1917c892ebf1Skrishna if (ep->ke_is_nxkey) { 1918c892ebf1Skrishna kssl_session_info_t *s; 1919c892ebf1Skrishna 1920c892ebf1Skrishna s = ep->ke_sessinfo; 1921c892ebf1Skrishna err = CRYPTO_SUCCESS; 1922c892ebf1Skrishna if (!s->is_valid_handle) { 1923c892ebf1Skrishna /* Reauthenticate to the provider */ 1924c892ebf1Skrishna if (s->do_reauth) { 1925c892ebf1Skrishna err = kssl_get_obj_handle(ep); 1926c892ebf1Skrishna if (err == CRYPTO_SUCCESS) { 1927c892ebf1Skrishna s->is_valid_handle = B_TRUE; 1928c892ebf1Skrishna s->do_reauth = B_FALSE; 1929c892ebf1Skrishna } 1930c892ebf1Skrishna } else 1931c892ebf1Skrishna err = CRYPTO_FAILED; 1932c892ebf1Skrishna } 1933c892ebf1Skrishna 1934c892ebf1Skrishna if (err == CRYPTO_SUCCESS) { 1935c892ebf1Skrishna ASSERT(s->is_valid_handle); 1936c892ebf1Skrishna err = crypto_decrypt_prov(s->prov, s->sid, 1937c892ebf1Skrishna &rsa_x509_mech, wrapped_pms_data, &s->key, 1938c892ebf1Skrishna NULL, pms_data, creqp); 1939c892ebf1Skrishna } 1940c892ebf1Skrishna 1941c892ebf1Skrishna /* 1942c892ebf1Skrishna * Deal with session specific errors. We translate to 1943c892ebf1Skrishna * the closest errno. 1944c892ebf1Skrishna */ 1945c892ebf1Skrishna switch (err) { 1946c892ebf1Skrishna case CRYPTO_KEY_HANDLE_INVALID: 1947c892ebf1Skrishna case CRYPTO_SESSION_HANDLE_INVALID: 1948c892ebf1Skrishna s->is_valid_handle = B_FALSE; 1949c892ebf1Skrishna s->do_reauth = B_TRUE; 1950c892ebf1Skrishna rverr = EINVAL; 1951c892ebf1Skrishna break; 1952c892ebf1Skrishna case CRYPTO_PIN_EXPIRED: 1953c892ebf1Skrishna case CRYPTO_PIN_LOCKED: 1954c892ebf1Skrishna rverr = EACCES; 1955c892ebf1Skrishna break; 1956c892ebf1Skrishna case CRYPTO_UNKNOWN_PROVIDER: 1957c892ebf1Skrishna rverr = ENXIO; 1958c892ebf1Skrishna break; 1959c892ebf1Skrishna } 1960c892ebf1Skrishna } else { 1961c28749e9Skais err = crypto_decrypt(&rsa_x509_mech, wrapped_pms_data, 1962c28749e9Skais privkey, NULL, pms_data, creqp); 1963c892ebf1Skrishna } 1964c28749e9Skais 1965c28749e9Skais switch (err) { 1966c28749e9Skais case CRYPTO_SUCCESS: 1967c28749e9Skais break; 1968c28749e9Skais 1969c28749e9Skais case CRYPTO_QUEUED: 1970c28749e9Skais /* 1971c28749e9Skais * Finish the master secret then the rest of key material 1972c28749e9Skais * derivation later. 1973c28749e9Skais */ 1974c28749e9Skais ssl->job.kjob = creq.cr_reqid; 1975c28749e9Skais ssl->job.buf = buf; 1976c28749e9Skais ssl->job.buflen = allocated; 1977c28749e9Skais ssl->hs_waitstate = wait_client_key_done; 1978c28749e9Skais return (0); 1979c28749e9Skais default: 198051dd2c77Svk199839 DTRACE_PROBE1(kssl_err__crypto_decrypt, int, err); 1981c28749e9Skais kmem_free(buf, allocated); 1982c892ebf1Skrishna return (rverr); 1983c28749e9Skais } 1984c28749e9Skais 1985c28749e9Skais pmslen = pms_data->cd_length; 1986c28749e9Skais pms = kssl_rsa_unwrap((uchar_t *)pms_data->cd_raw.iov_base, &pmslen); 1987c28749e9Skais 1988c28749e9Skais /* generate master key and save it in the ssl sid structure */ 1989c28749e9Skais if (IS_TLS(ssl)) { 1990c28749e9Skais err = kssl_generate_tls_ms(ssl, pms, pmslen); 1991c28749e9Skais if (!CRYPTO_ERR(err)) 1992c28749e9Skais err = kssl_generate_tls_keyblock(ssl); 1993c28749e9Skais } else { 1994c28749e9Skais kssl_generate_ssl_ms(ssl, pms, pmslen); 1995c28749e9Skais kssl_generate_keyblock(ssl); 1996c28749e9Skais } 1997c28749e9Skais 1998c28749e9Skais if (err == CRYPTO_SUCCESS) 1999c28749e9Skais ssl->hs_waitstate = wait_change_cipher; 2000c28749e9Skais 2001c28749e9Skais ssl->activeinput = B_FALSE; 2002c28749e9Skais 2003c28749e9Skais kmem_free(buf, allocated); 2004c28749e9Skais 2005c28749e9Skais return (0); 2006c28749e9Skais } 2007c28749e9Skais 2008c28749e9Skais static int 2009c28749e9Skais kssl_handle_finished(ssl_t *ssl, mblk_t *mp, int msglen) 2010c28749e9Skais { 2011c28749e9Skais int err; 2012c28749e9Skais size_t finish_len; 2013c28749e9Skais int hashcompare; 2014c28749e9Skais 2015c28749e9Skais ASSERT(ssl->msg.type == finished); 2016c28749e9Skais ASSERT(ssl->hs_waitstate == wait_finished); 2017c28749e9Skais 2018c28749e9Skais if (IS_TLS(ssl)) 2019c28749e9Skais finish_len = TLS_FINISHED_SIZE; 2020c28749e9Skais else 2021c28749e9Skais finish_len = KSSL_SSL3_FIN_MSGLEN; 2022c28749e9Skais 2023c28749e9Skais if (msglen != finish_len) { 2024c28749e9Skais kssl_send_alert(ssl, alert_fatal, illegal_parameter); 2025c28749e9Skais return (EBADMSG); 2026c28749e9Skais } 2027c28749e9Skais 2028c28749e9Skais if (IS_TLS(ssl)) { 2029c28749e9Skais hashcompare = bcmp(mp->b_rptr, ssl->hs_hashes.tlshash, 2030c28749e9Skais finish_len); 2031c28749e9Skais } else { 2032c28749e9Skais hashcompare = bcmp(mp->b_rptr, &ssl->hs_hashes, finish_len); 2033c28749e9Skais } 2034c28749e9Skais 2035c28749e9Skais /* The handshake hashes should be computed by now */ 2036c28749e9Skais if (hashcompare != 0) { 2037c28749e9Skais kssl_send_alert(ssl, alert_fatal, handshake_failure); 2038c28749e9Skais return (EBADMSG); 2039c28749e9Skais } 2040c28749e9Skais 2041c28749e9Skais mp->b_rptr += msglen; 2042c28749e9Skais 2043c28749e9Skais ssl->hs_waitstate = idle_handshake; 2044c28749e9Skais 2045c28749e9Skais if (ssl->resumed == B_TRUE) { 2046c28749e9Skais ssl->activeinput = B_FALSE; 2047c28749e9Skais return (0); 2048c28749e9Skais } 2049c28749e9Skais 2050c28749e9Skais err = kssl_send_change_cipher_specs(ssl); 2051c28749e9Skais if (err != 0) { 2052c28749e9Skais return (err); 2053c28749e9Skais } 2054c28749e9Skais err = kssl_send_finished(ssl, 0); 2055c28749e9Skais if (err != 0) { 2056c28749e9Skais return (err); 2057c28749e9Skais } 2058c28749e9Skais 2059c28749e9Skais kssl_cache_sid(&ssl->sid, ssl->kssl_entry); 2060c28749e9Skais ssl->activeinput = B_FALSE; 2061c28749e9Skais 2062c28749e9Skais return (0); 2063c28749e9Skais } 2064c28749e9Skais 2065c28749e9Skais #define KSSL2_CH_MIN_RECSZ (9) 2066c28749e9Skais 2067c28749e9Skais /* 2068c28749e9Skais * This method is needed to handle clients which send the 2069c28749e9Skais * SSLv2/SSLv3 handshake for backwards compat with SSLv2 servers. 2070c28749e9Skais * We are not really doing SSLv2 here, just handling the header 2071c28749e9Skais * and then switching to SSLv3. 2072c28749e9Skais */ 2073c28749e9Skais int 2074c28749e9Skais kssl_handle_v2client_hello(ssl_t *ssl, mblk_t *mp, int recsz) 2075c28749e9Skais { 2076c28749e9Skais uchar_t *recend; 2077c28749e9Skais int err; 2078c28749e9Skais SSL3AlertDescription desc = illegal_parameter; 2079c28749e9Skais uint_t randlen; 2080c28749e9Skais uint_t sidlen; 208151144063SKrishna Yenduri uint_t cslen; 2082c28749e9Skais uchar_t *suitesp; 2083c28749e9Skais uchar_t *rand; 2084c28749e9Skais uint_t i, j; 208511d0a659SVladimir Kotal uint16_t suite, selected_suite; 2086c28749e9Skais int ch_recsz = KSSL2_CH_MIN_RECSZ; 208711d0a659SVladimir Kotal boolean_t suite_found = B_FALSE; 2088c28749e9Skais 2089c28749e9Skais ASSERT(mp->b_wptr >= mp->b_rptr + recsz); 2090c28749e9Skais ASSERT(ssl->hs_waitstate == wait_client_hello); 2091c28749e9Skais ASSERT(ssl->resumed == B_FALSE); 2092c28749e9Skais 2093c28749e9Skais if (recsz < ch_recsz) { 209465d18457SVladimir Kotal DTRACE_PROBE2(kssl_err__reclen_less_than_minimum, 209565d18457SVladimir Kotal int, recsz, int, ch_recsz); 2096c28749e9Skais goto falert; 2097c28749e9Skais } 2098c28749e9Skais 2099c28749e9Skais MD5Init(&ssl->hs_md5); 2100c28749e9Skais SHA1Init(&ssl->hs_sha1); 2101c28749e9Skais 2102c28749e9Skais kssl_update_handshake_hashes(ssl, mp->b_rptr, recsz); 2103c28749e9Skais 2104c28749e9Skais recend = mp->b_rptr + recsz; 2105c28749e9Skais 2106c28749e9Skais if (*mp->b_rptr != 1) { 210765d18457SVladimir Kotal DTRACE_PROBE1(kssl_err__invalid_version, uint_t, *mp->b_rptr); 2108c28749e9Skais goto falert; 2109c28749e9Skais } 2110c28749e9Skais mp->b_rptr += 3; 2111c28749e9Skais 211251144063SKrishna Yenduri cslen = ((uint_t)mp->b_rptr[0] << 8) + (uint_t)mp->b_rptr[1]; 2113c28749e9Skais sidlen = ((uint_t)mp->b_rptr[2] << 8) + (uint_t)mp->b_rptr[3]; 2114c28749e9Skais randlen = ((uint_t)mp->b_rptr[4] << 8) + (uint_t)mp->b_rptr[5]; 211551144063SKrishna Yenduri if (cslen % 3 != 0) { 211651144063SKrishna Yenduri DTRACE_PROBE1(kssl_err__cipher_suites_len_error, uint_t, cslen); 2117c28749e9Skais goto falert; 2118c28749e9Skais } 2119c28749e9Skais if (randlen < SSL_MIN_CHALLENGE_BYTES || 2120c28749e9Skais randlen > SSL_MAX_CHALLENGE_BYTES) { 212151dd2c77Svk199839 DTRACE_PROBE1(kssl_err__randlen_out_of_range, 212251dd2c77Svk199839 uint_t, randlen); 2123c28749e9Skais goto falert; 2124c28749e9Skais } 2125c28749e9Skais mp->b_rptr += 6; 212651144063SKrishna Yenduri ch_recsz += cslen + sidlen + randlen; 2127c28749e9Skais if (recsz != ch_recsz) { 212865d18457SVladimir Kotal DTRACE_PROBE2(kssl_err__invalid_message_len_sum, 212965d18457SVladimir Kotal int, recsz, int, ch_recsz); 2130c28749e9Skais goto falert; 2131c28749e9Skais } 2132c28749e9Skais suitesp = mp->b_rptr; 213351144063SKrishna Yenduri rand = suitesp + cslen + sidlen; 2134c28749e9Skais if (randlen < SSL3_RANDOM_LENGTH) { 2135c28749e9Skais bzero(ssl->client_random, SSL3_RANDOM_LENGTH); 2136c28749e9Skais } 2137c28749e9Skais bcopy(rand, &ssl->client_random[SSL3_RANDOM_LENGTH - randlen], 2138c28749e9Skais randlen); 2139c28749e9Skais 2140c28749e9Skais for (i = 0; i < ssl->kssl_entry->kssl_cipherSuites_nentries; i++) { 2141c28749e9Skais suite = ssl->kssl_entry->kssl_cipherSuites[i]; 214251144063SKrishna Yenduri for (j = 0; j < cslen; j += 3) { 214311d0a659SVladimir Kotal DTRACE_PROBE2(kssl_cipher_suite_check_v2, 214411d0a659SVladimir Kotal uint16_t, suite, 214511d0a659SVladimir Kotal uint16_t, 214611d0a659SVladimir Kotal (uint16_t)((suitesp[j+1] << 8) + suitesp[j+2])); 2147c28749e9Skais if (suitesp[j] != 0) { 2148c28749e9Skais continue; 2149c28749e9Skais } 2150c28749e9Skais 215111d0a659SVladimir Kotal /* Check for regular (true) cipher suite. */ 2152c28749e9Skais if (suitesp[j + 1] == ((suite >> 8) & 0xff) && 2153c28749e9Skais suitesp[j + 2] == (suite & 0xff)) { 215411d0a659SVladimir Kotal DTRACE_PROBE1(kssl_cipher_suite_found, 215511d0a659SVladimir Kotal uint16_t, suite); 215611d0a659SVladimir Kotal suite_found = B_TRUE; 215711d0a659SVladimir Kotal selected_suite = suite; 215811d0a659SVladimir Kotal } 215911d0a659SVladimir Kotal 216011d0a659SVladimir Kotal /* Check for SCSV. */ 216111d0a659SVladimir Kotal if (suitesp[j + 1] == ((SSL_SCSV >> 8) & 0xff) && 216211d0a659SVladimir Kotal suitesp[j + 2] == (SSL_SCSV & 0xff)) { 216311d0a659SVladimir Kotal DTRACE_PROBE(kssl_scsv_found); 216411d0a659SVladimir Kotal ssl->secure_renegotiation = B_TRUE; 216511d0a659SVladimir Kotal } 216611d0a659SVladimir Kotal /* 216711d0a659SVladimir Kotal * If we got cipher suite match and SCSV or went 216811d0a659SVladimir Kotal * through the whole list of client cipher suites 216911d0a659SVladimir Kotal * (hence we know if SCSV was present or not) we 217011d0a659SVladimir Kotal * can terminate the cycle now. 217111d0a659SVladimir Kotal */ 217211d0a659SVladimir Kotal if (suite_found && 217311d0a659SVladimir Kotal (ssl->secure_renegotiation || (i > 0))) 2174c28749e9Skais break; 2175c28749e9Skais } 217611d0a659SVladimir Kotal if (suite_found) 2177c28749e9Skais break; 2178c28749e9Skais } 217911d0a659SVladimir Kotal if (!suite_found) { 218051dd2c77Svk199839 DTRACE_PROBE(kssl_err__no_SSLv2_cipher_suite); 2181c28749e9Skais ssl->activeinput = B_FALSE; 218265d18457SVladimir Kotal /* 218365d18457SVladimir Kotal * If there is no fallback point terminate the handshake with 218465d18457SVladimir Kotal * SSL alert otherwise return with SSL_MISS. 218565d18457SVladimir Kotal */ 218665d18457SVladimir Kotal if (ssl->kssl_entry->ke_fallback_head == NULL) { 218765d18457SVladimir Kotal DTRACE_PROBE(kssl_no_fallback); 218865d18457SVladimir Kotal desc = handshake_failure; 218965d18457SVladimir Kotal goto falert; 219065d18457SVladimir Kotal } else { 2191c28749e9Skais return (SSL_MISS); 2192c28749e9Skais } 219365d18457SVladimir Kotal } 2194c28749e9Skais 2195c28749e9Skais mp->b_rptr = recend; 2196c28749e9Skais 2197c28749e9Skais for (i = 0; i < cipher_suite_defs_nentries; i++) { 219811d0a659SVladimir Kotal if (selected_suite == cipher_suite_defs[i].suite) { 2199c28749e9Skais break; 2200c28749e9Skais } 2201c28749e9Skais } 2202c28749e9Skais 2203c28749e9Skais ASSERT(i < cipher_suite_defs_nentries); 2204c28749e9Skais 220511d0a659SVladimir Kotal ssl->pending_cipher_suite = selected_suite; 2206c28749e9Skais ssl->pending_malg = cipher_suite_defs[i].malg; 2207c28749e9Skais ssl->pending_calg = cipher_suite_defs[i].calg; 2208c28749e9Skais ssl->pending_keyblksz = cipher_suite_defs[i].keyblksz; 2209c28749e9Skais 2210c28749e9Skais ASSERT(ssl->sid.cached == B_FALSE); 2211c28749e9Skais 2212c28749e9Skais (void) random_get_pseudo_bytes(ssl->sid.session_id, 2213c28749e9Skais SSL3_SESSIONID_BYTES); 2214c28749e9Skais ssl->sid.client_addr = ssl->faddr; 221511d0a659SVladimir Kotal ssl->sid.cipher_suite = selected_suite; 2216c28749e9Skais 2217c28749e9Skais err = kssl_send_server_hello(ssl); 2218c28749e9Skais if (err != 0) { 2219c28749e9Skais return (err); 2220c28749e9Skais } 2221c28749e9Skais err = kssl_send_certificate_and_server_hello_done(ssl); 2222c28749e9Skais if (err != 0) { 2223c28749e9Skais return (err); 2224c28749e9Skais } 2225c28749e9Skais KSSL_COUNTER(full_handshakes, 1); 2226c28749e9Skais ssl->hs_waitstate = wait_client_key; 2227c28749e9Skais ssl->activeinput = B_FALSE; 2228c28749e9Skais return (0); 2229c28749e9Skais 2230c28749e9Skais falert: 2231c28749e9Skais kssl_send_alert(ssl, alert_fatal, desc); 2232c28749e9Skais ssl->activeinput = B_FALSE; 2233c28749e9Skais return (EBADMSG); 2234c28749e9Skais } 2235c28749e9Skais 2236c28749e9Skais /* 2237c28749e9Skais * Call back routine for asynchronously submitted RSA decryption jobs. 223851144063SKrishna Yenduri * This routine retrieves the pre-master secret, and proceeds to generate 2239c28749e9Skais * the remaining key materials. 2240c28749e9Skais */ 2241c28749e9Skais static void 2242c28749e9Skais kssl_cke_done(void *arg, int status) 2243c28749e9Skais { 2244c28749e9Skais int ret = 0; 2245c28749e9Skais uchar_t *pms; 2246c28749e9Skais size_t pmslen; 2247c28749e9Skais crypto_data_t *pms_data; 2248c28749e9Skais kssl_cmd_t kssl_cmd = KSSL_CMD_NONE; 2249c28749e9Skais ssl_t *ssl = (ssl_t *)arg; 2250c28749e9Skais mblk_t *alertmp; 2251c28749e9Skais kssl_callback_t cbfn; 2252c28749e9Skais void *cbarg; 2253c28749e9Skais 2254c28749e9Skais mutex_enter(&ssl->kssl_lock); 2255c28749e9Skais 2256c28749e9Skais ASSERT(ssl->msg.type == client_key_exchange); 2257c28749e9Skais ASSERT(ssl->hs_waitstate == wait_client_key_done); 2258c28749e9Skais 2259c28749e9Skais if (status != CRYPTO_SUCCESS) { 2260c28749e9Skais kssl_send_alert(ssl, alert_fatal, decrypt_error); 2261c28749e9Skais kssl_cmd = KSSL_CMD_SEND; 2262c28749e9Skais goto out; 2263c28749e9Skais } 2264c28749e9Skais 2265c28749e9Skais pms_data = (crypto_data_t *)(ssl->job.buf); 2266c28749e9Skais 2267c28749e9Skais ASSERT(pms_data != NULL); 2268c28749e9Skais 2269c28749e9Skais pmslen = pms_data->cd_length; 2270c28749e9Skais pms = kssl_rsa_unwrap((uchar_t *)pms_data->cd_raw.iov_base, &pmslen); 2271c28749e9Skais 2272c28749e9Skais /* generate master key and save it in the ssl sid structure */ 2273c28749e9Skais if (IS_TLS(ssl)) { 2274c28749e9Skais ret = kssl_generate_tls_ms(ssl, pms, pmslen); 2275c28749e9Skais if (!CRYPTO_ERR(ret)) 2276c28749e9Skais ret = kssl_generate_tls_keyblock(ssl); 2277c28749e9Skais } else { 2278c28749e9Skais kssl_generate_ssl_ms(ssl, pms, pmslen); 2279c28749e9Skais kssl_generate_keyblock(ssl); 2280c28749e9Skais } 2281c28749e9Skais 2282c28749e9Skais if (ret == CRYPTO_SUCCESS) 2283c28749e9Skais ssl->hs_waitstate = wait_change_cipher; 2284c28749e9Skais 2285c28749e9Skais out: 2286c28749e9Skais kmem_free(ssl->job.buf, ssl->job.buflen); 2287c28749e9Skais 2288c28749e9Skais ssl->job.kjob = 0; 2289c28749e9Skais ssl->job.buf = NULL; 2290c28749e9Skais ssl->job.buflen = 0; 2291c28749e9Skais 2292c28749e9Skais ssl->activeinput = B_FALSE; 2293c28749e9Skais 2294c28749e9Skais cbfn = ssl->cke_callback_func; 2295c28749e9Skais cbarg = ssl->cke_callback_arg; 2296c28749e9Skais alertmp = ssl->alert_sendbuf; 2297c28749e9Skais ssl->alert_sendbuf = NULL; 2298c28749e9Skais 2299dd49f125SAnders Persson /* dropped by callback when it has completed */ 2300dd49f125SAnders Persson ssl->async_ops_pending++; 2301c28749e9Skais mutex_exit(&ssl->kssl_lock); 2302c28749e9Skais 2303c28749e9Skais /* Now call the callback routine */ 2304c28749e9Skais (*(cbfn))(cbarg, alertmp, kssl_cmd); 2305c28749e9Skais } 2306c28749e9Skais 2307c28749e9Skais /* 2308c28749e9Skais * Returns the first complete contiguous record out of rec_ass_head 2309c28749e9Skais * The record is returned in a separate contiguous mblk, rec_ass_head is 2310c28749e9Skais * left pointing to the next record in the queue. 2311c28749e9Skais * 2312c28749e9Skais * The output looks as follows: 2313c28749e9Skais * 2314c28749e9Skais * |--------|---------- .... -----|<---------->|<----------->|--- ... ---| 2315c28749e9Skais * ^ ^ ^ mac_size pad_size ^ 2316c28749e9Skais * | |___ b_rptr b_wptr __| | 2317c28749e9Skais * | | 2318c28749e9Skais * |___ db_base db_lim ___| 2319c28749e9Skais */ 2320c28749e9Skais mblk_t * 2321c28749e9Skais kssl_get_next_record(ssl_t *ssl) 2322c28749e9Skais { 2323c28749e9Skais mblk_t *mp, *retmp; 2324c28749e9Skais int rhsz = SSL3_HDR_LEN; 2325c28749e9Skais uint16_t rec_sz; 2326c28749e9Skais int mpsz, total_size; 2327c28749e9Skais SSL3ContentType content_type; 2328c28749e9Skais 2329c28749e9Skais ASSERT(MUTEX_HELD(&ssl->kssl_lock)); 2330c28749e9Skais 2331c28749e9Skais mp = ssl->rec_ass_head; 2332c28749e9Skais if (mp == NULL) 2333c28749e9Skais return (NULL); 2334c28749e9Skais 2335c28749e9Skais /* Fast path: when mp has at least a complete record */ 2336c28749e9Skais if (MBLKL(mp) < rhsz) { 233751dd2c77Svk199839 DTRACE_PROBE1(kssl_mblk__incomplete_header, 233851dd2c77Svk199839 mblk_t *, mp); 2339c28749e9Skais /* Not even a complete header in there yet */ 2340c28749e9Skais if (msgdsize(mp) < rhsz) { 2341c28749e9Skais return (NULL); 2342c28749e9Skais } 2343c28749e9Skais 2344c28749e9Skais if (!pullupmsg(mp, rhsz)) { 2345c28749e9Skais kssl_send_alert(ssl, alert_fatal, internal_error); 2346c28749e9Skais freemsg(mp); 2347c28749e9Skais ssl->rec_ass_head = ssl->rec_ass_tail = NULL; 2348c28749e9Skais return (NULL); 2349c28749e9Skais } 2350c28749e9Skais } 2351c28749e9Skais content_type = (SSL3ContentType)mp->b_rptr[0]; 2352c28749e9Skais if (content_type == content_handshake_v2) { 235351dd2c77Svk199839 DTRACE_PROBE1(kssl_mblk__ssl_v2, mblk_t *, mp); 2354c28749e9Skais rec_sz = (uint16_t)mp->b_rptr[1]; 2355c28749e9Skais rhsz = 2; 2356c28749e9Skais } else { 235751dd2c77Svk199839 DTRACE_PROBE1(kssl_mblk__ssl_v3, mblk_t *, mp); 2358c28749e9Skais uint8_t *rec_sz_p = (uint8_t *)mp->b_rptr + 3; 2359c28749e9Skais rec_sz = BE16_TO_U16(rec_sz_p); 2360c28749e9Skais } 2361c28749e9Skais 2362c28749e9Skais /* 2363c28749e9Skais * same tests as above. Only rare very fragmented cases will 2364c28749e9Skais * incur the cost of msgdsize() and msgpullup(). Well formed 2365c28749e9Skais * packets will fall in the most frequent fast path. 2366c28749e9Skais */ 2367c28749e9Skais total_size = rhsz + rec_sz; 2368c28749e9Skais 2369c28749e9Skais /* 2370c28749e9Skais * Missing: defensive against record fabricated with longer than 2371c28749e9Skais * MAX record length. 2372c28749e9Skais */ 2373c28749e9Skais if (MBLKL(mp) < total_size) { 237451dd2c77Svk199839 DTRACE_PROBE2(kssl_mblk__smaller_than_total_size, 237551dd2c77Svk199839 mblk_t *, mp, int, total_size); 2376c28749e9Skais /* Not a complete record yet. Keep accumulating */ 2377c28749e9Skais if (msgdsize(mp) < total_size) { 2378c28749e9Skais return (NULL); 2379c28749e9Skais } 2380c28749e9Skais 2381c28749e9Skais if (!pullupmsg(mp, total_size)) { 2382c28749e9Skais kssl_send_alert(ssl, alert_fatal, internal_error); 2383c28749e9Skais freemsg(mp); 2384c28749e9Skais ssl->rec_ass_head = ssl->rec_ass_tail = NULL; 2385c28749e9Skais return (NULL); 2386c28749e9Skais } 2387c28749e9Skais } 2388c28749e9Skais mpsz = MBLKL(mp); /* could've changed after the pullup */ 2389c28749e9Skais 2390c28749e9Skais if (mpsz > total_size) { 239151dd2c77Svk199839 DTRACE_PROBE2(kssl_mblk__bigger_than_total_size, 239251dd2c77Svk199839 mblk_t *, mp, int, total_size); 2393c28749e9Skais /* gotta allocate a new block */ 2394c28749e9Skais if ((retmp = dupb(mp)) == NULL) { 2395c28749e9Skais kssl_send_alert(ssl, alert_fatal, internal_error); 2396c28749e9Skais freemsg(mp); 2397c28749e9Skais ssl->rec_ass_head = ssl->rec_ass_tail = NULL; 2398c28749e9Skais return (NULL); 2399c28749e9Skais } 2400c28749e9Skais 2401c28749e9Skais retmp->b_wptr = retmp->b_rptr + total_size; 2402c28749e9Skais mp->b_rptr += total_size; 2403c28749e9Skais ssl->rec_ass_head = mp; 2404c28749e9Skais } else { 240551dd2c77Svk199839 DTRACE_PROBE2(kssl_mblk__equal_to_total_size, 240651dd2c77Svk199839 mblk_t *, mp, int, total_size); 2407c28749e9Skais ASSERT(mpsz == total_size); 2408c28749e9Skais ssl->rec_ass_head = mp->b_cont; 2409c28749e9Skais mp->b_cont = NULL; 2410c28749e9Skais retmp = mp; 2411c28749e9Skais } 2412c28749e9Skais /* Adjust the tail */ 2413c28749e9Skais if ((mp = ssl->rec_ass_tail = ssl->rec_ass_head) != NULL) { 2414c28749e9Skais for (; mp->b_cont != NULL; mp = mp->b_cont) { 2415c28749e9Skais ssl->rec_ass_tail = mp->b_cont; 2416c28749e9Skais } 2417c28749e9Skais } 2418c28749e9Skais 2419c28749e9Skais return (retmp); 2420c28749e9Skais } 2421c28749e9Skais 2422c28749e9Skais 2423c28749e9Skais static void 2424c28749e9Skais kssl_mblksfree(ssl_t *ssl) 2425c28749e9Skais { 2426c28749e9Skais 2427c28749e9Skais ASSERT(ssl != NULL); 2428c28749e9Skais 2429c28749e9Skais if (ssl->rec_ass_head != NULL) { 2430c28749e9Skais freemsg(ssl->rec_ass_head); 2431c28749e9Skais } 2432c28749e9Skais ssl->rec_ass_head = NULL; 2433c28749e9Skais ssl->rec_ass_tail = NULL; 2434c28749e9Skais 2435c28749e9Skais if (ssl->msg.head != NULL) { 2436c28749e9Skais freemsg(ssl->msg.head); 2437c28749e9Skais } 2438c28749e9Skais ssl->msg.head = NULL; 2439c28749e9Skais ssl->msg.tail = NULL; 2440c28749e9Skais 2441c28749e9Skais if (ssl->handshake_sendbuf != NULL) { 2442c28749e9Skais freemsg(ssl->handshake_sendbuf); 2443c28749e9Skais ssl->handshake_sendbuf = NULL; 2444c28749e9Skais } 2445c28749e9Skais if (ssl->alert_sendbuf != NULL) { 2446c28749e9Skais freemsg(ssl->alert_sendbuf); 2447c28749e9Skais ssl->alert_sendbuf = NULL; 2448c28749e9Skais } 2449c28749e9Skais } 2450c28749e9Skais 2451c28749e9Skais static void 2452c28749e9Skais kssl_specsfree(ssl_t *ssl) 2453c28749e9Skais { 2454c28749e9Skais KSSLCipherSpec *spec = &ssl->spec[KSSL_READ]; 2455c28749e9Skais 2456c28749e9Skais if (spec->cipher_ctx != NULL) { 2457c28749e9Skais crypto_cancel_ctx(spec->cipher_ctx); 2458c28749e9Skais spec->cipher_ctx = 0; 2459c28749e9Skais } 2460c28749e9Skais 2461c28749e9Skais spec = &ssl->spec[KSSL_WRITE]; 2462c28749e9Skais 2463c28749e9Skais if (spec->cipher_ctx != NULL) { 2464c28749e9Skais crypto_cancel_ctx(spec->cipher_ctx); 2465c28749e9Skais spec->cipher_ctx = 0; 2466c28749e9Skais } 2467c28749e9Skais } 2468c28749e9Skais 2469c28749e9Skais /* 2470c28749e9Skais * Frees the ssl structure (aka the context of an SSL session). 2471c28749e9Skais * Any pending crypto jobs are cancelled. 2472c28749e9Skais * Any initiated crypto contexts are freed as well. 2473c28749e9Skais */ 2474c28749e9Skais void 2475c28749e9Skais kssl_free_context(ssl_t *ssl) 2476c28749e9Skais { 2477dd49f125SAnders Persson crypto_req_id_t reqid; 2478dd49f125SAnders Persson 2479c28749e9Skais ASSERT(ssl != NULL); 2480c28749e9Skais if (!(MUTEX_HELD(&ssl->kssl_lock))) { 2481c28749e9Skais /* we're coming from an external API entry point */ 2482c28749e9Skais mutex_enter(&ssl->kssl_lock); 2483c28749e9Skais } 2484c28749e9Skais 2485dd49f125SAnders Persson /* 2486dd49f125SAnders Persson * Cancel any active crypto request and wait for pending async 2487dd49f125SAnders Persson * operations to complete. We loop here because the async thread 2488dd49f125SAnders Persson * might submit a new cryto request. 2489dd49f125SAnders Persson */ 2490dd49f125SAnders Persson do { 2491c28749e9Skais if (ssl->job.kjob != NULL) { 2492dd49f125SAnders Persson /* 2493dd49f125SAnders Persson * Drop the lock before canceling the request; 2494dd49f125SAnders Persson * otherwise we might deadlock if the completion 2495dd49f125SAnders Persson * callback is running. 2496dd49f125SAnders Persson */ 2497dd49f125SAnders Persson reqid = ssl->job.kjob; 2498dd49f125SAnders Persson mutex_exit(&ssl->kssl_lock); 2499dd49f125SAnders Persson crypto_cancel_req(reqid); 2500dd49f125SAnders Persson mutex_enter(&ssl->kssl_lock); 2501c28749e9Skais 2502dd49f125SAnders Persson /* completion callback might have done the cleanup */ 2503dd49f125SAnders Persson if (ssl->job.kjob != NULL) { 2504dd49f125SAnders Persson kmem_free(ssl->job.buf, ssl->job.buflen); 2505c28749e9Skais ssl->job.kjob = 0; 2506c28749e9Skais ssl->job.buf = NULL; 2507c28749e9Skais ssl->job.buflen = 0; 2508c28749e9Skais } 2509dd49f125SAnders Persson } 2510dd49f125SAnders Persson while (ssl->async_ops_pending > 0) 2511dd49f125SAnders Persson cv_wait(&ssl->async_cv, &ssl->kssl_lock); 2512dd49f125SAnders Persson } while (ssl->job.kjob != NULL); 2513c28749e9Skais 2514c28749e9Skais kssl_mblksfree(ssl); 2515c28749e9Skais kssl_specsfree(ssl); 2516c28749e9Skais 2517c28749e9Skais KSSL_ENTRY_REFRELE(ssl->kssl_entry); 2518c28749e9Skais ssl->kssl_entry = NULL; 2519c28749e9Skais 2520c28749e9Skais mutex_exit(&ssl->kssl_lock); 2521c28749e9Skais 2522c28749e9Skais kmem_cache_free(kssl_cache, ssl); 2523c28749e9Skais } 2524