Home | History | Annotate | Download | only in kssl
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #include <sys/types.h>
     27 #include <sys/stream.h>
     28 #include <sys/strsun.h>
     29 #include <sys/kmem.h>
     30 #include <sys/cpuvar.h>
     31 #include <sys/atomic.h>
     32 #include <sys/sysmacros.h>
     33 
     34 #include <inet/common.h>
     35 #include <inet/ip.h>
     36 
     37 #include <sys/systm.h>
     38 #include <sys/param.h>
     39 #include <sys/tihdr.h>
     40 
     41 #include "ksslimpl.h"
     42 #include "ksslproto.h"
     43 #include "ksslapi.h"
     44 
     45 static kssl_cmd_t kssl_handle_any_record(kssl_ctx_t ctx, mblk_t *mp,
     46     mblk_t **decrmp, kssl_callback_t cbfn, void *arg);
     47 static boolean_t kssl_enqueue(kssl_chain_t **head, void *item);
     48 static void kssl_dequeue(kssl_chain_t **head, void *item);
     49 static kssl_status_t kssl_build_single_record(ssl_t *ssl, mblk_t *mp);
     50 
     51 /*
     52  * The socket T_bind_req message is intercepted and re-routed here
     53  * to see is there is SSL relevant job to do, based on the kssl config
     54  * in the kssl_entry_tab.
     55  * Looks up the kernel SSL proxy table, to find an entry that matches the
     56  * same serveraddr, and has one of the following two criteria:
     57  * 1. in_port is an ssl_port. This endpoint can be used later as a fallback
     58  *    to complete connections that cannot be handled by the SSL kernel proxy
     59  *    (typically non supported ciphersuite). The cookie for the calling client
     60  *    is saved with the kssl_entry to be retrieved for the fallback.
     61  *    The function returns KSSL_HAS_PROXY.
     62  *
     63  * 2. in_port is a proxy port for another ssl port. The ssl port is then
     64  *    substituted to the in_port in the bind_req TPI structure, so that
     65  *    the bind falls through to the SSL port. At the end of this operation,
     66  *    all the packets arriving to the SSL port will be delivered to an
     67  *    accepted endpoint child of this bound socket.
     68  *    The  kssl_entry_t is returned in *ksslent, for later use by the
     69  *    lower modules' SSL hooks that handle the Handshake messages.
     70  *    The function returns KSSL_IS_PROXY.
     71  *
     72  * The function returns KSSL_NO_PROXY otherwise.
     73  */
     74 
     75 kssl_endpt_type_t
     76 kssl_check_proxy(mblk_t *bindmp, void *cookie, kssl_ent_t *ksslent)
     77 {
     78 	int i;
     79 	kssl_endpt_type_t ret;
     80 	kssl_entry_t *ep;
     81 	sin_t *sin;
     82 	sin6_t *sin6;
     83 	struct T_bind_req *tbr;
     84 	in6_addr_t mapped_v4addr;
     85 	in6_addr_t *v6addr;
     86 	in_port_t in_port;
     87 
     88 	if (kssl_entry_tab_nentries == 0) {
     89 		return (KSSL_NO_PROXY);
     90 	}
     91 
     92 	ret = KSSL_NO_PROXY;
     93 
     94 	tbr = (struct T_bind_req *)bindmp->b_rptr;
     95 	sin = (sin_t *)(bindmp->b_rptr + tbr->ADDR_offset);
     96 
     97 	switch (tbr->ADDR_length) {
     98 	case sizeof (sin_t):
     99 		in_port = ntohs(sin->sin_port);
    100 		IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &mapped_v4addr);
    101 		v6addr = &mapped_v4addr;
    102 		break;
    103 
    104 	case sizeof (sin6_t):
    105 		sin6 = (sin6_t *)sin;
    106 		in_port = ntohs(sin6->sin6_port);
    107 		v6addr = &sin6->sin6_addr;
    108 		break;
    109 
    110 	default:
    111 		return (ret);
    112 	}
    113 
    114 	mutex_enter(&kssl_tab_mutex);
    115 
    116 	for (i = 0; i < kssl_entry_tab_size; i++) {
    117 		if ((ep = kssl_entry_tab[i]) == NULL)
    118 			continue;
    119 
    120 		if (IN6_ARE_ADDR_EQUAL(&ep->ke_laddr, v6addr) ||
    121 		    IN6_IS_ADDR_UNSPECIFIED(&ep->ke_laddr)) {
    122 
    123 			/* This is an SSL port to fallback to */
    124 			if (ep->ke_ssl_port == in_port) {
    125 
    126 				/*
    127 				 * Let's see first if there's at least
    128 				 * an endpoint for a proxy server.
    129 				 * If there's none, then we return as we have
    130 				 * no proxy, so that the bind() to the
    131 				 * transport layer goes through.
    132 				 * The calling module will ask for this
    133 				 * cookie if it wants to fall back to it,
    134 				 * so add this one to the list of fallback
    135 				 * clients.
    136 				 */
    137 				if (!kssl_enqueue((kssl_chain_t **)
    138 				    &(ep->ke_fallback_head), cookie)) {
    139 					break;
    140 				}
    141 
    142 				/*
    143 				 * Now transform the T_BIND_REQ into
    144 				 * a T_BIND_ACK.
    145 				 */
    146 				tbr->PRIM_type = T_BIND_ACK;
    147 				bindmp->b_datap->db_type = M_PCPROTO;
    148 
    149 				KSSL_ENTRY_REFHOLD(ep);
    150 				*ksslent = (kssl_ent_t)ep;
    151 
    152 				ret = KSSL_HAS_PROXY;
    153 				break;
    154 			}
    155 
    156 			/* This is a proxy port. */
    157 			if (ep->ke_proxy_port == in_port) {
    158 				mblk_t *entmp;
    159 
    160 				/* Append this entry to the bind_req mblk */
    161 
    162 				entmp = allocb(sizeof (kssl_entry_t),
    163 				    BPRI_MED);
    164 				if (entmp == NULL)
    165 					break;
    166 				*((kssl_entry_t **)entmp->b_rptr) = ep;
    167 
    168 				entmp->b_wptr = entmp->b_rptr +
    169 				    sizeof (kssl_entry_t);
    170 
    171 				bindmp->b_cont = entmp;
    172 
    173 				/* Add the caller's cookie to proxies list */
    174 
    175 				if (!kssl_enqueue((kssl_chain_t **)
    176 				    &(ep->ke_proxy_head), cookie)) {
    177 					freeb(bindmp->b_cont);
    178 					bindmp->b_cont = NULL;
    179 					break;
    180 				}
    181 
    182 				/*
    183 				 * Make this look  like the SSL port to the
    184 				 * transport below
    185 				 */
    186 				sin->sin_port = htons(ep->ke_ssl_port);
    187 
    188 				tbr->PRIM_type = T_SSL_PROXY_BIND_REQ;
    189 
    190 				KSSL_ENTRY_REFHOLD(ep);
    191 				*ksslent = (kssl_ent_t)ep;
    192 
    193 				ret = KSSL_IS_PROXY;
    194 				break;
    195 			}
    196 		}
    197 	}
    198 
    199 	mutex_exit(&kssl_tab_mutex);
    200 	return (ret);
    201 }
    202 
    203 /*
    204  * Retrieved an endpoint "bound" to the SSL entry.
    205  * Such endpoint has previously called kssl_check_proxy(), got itself
    206  * linked to the kssl_entry's ke_fallback_head list.
    207  * This routine returns the cookie from that SSL entry ke_fallback_head list.
    208  */
    209 void *
    210 kssl_find_fallback(kssl_ent_t ksslent)
    211 {
    212 	kssl_entry_t *kssl_entry = (kssl_entry_t *)ksslent;
    213 
    214 	if (kssl_entry->ke_fallback_head != NULL)
    215 		return (kssl_entry->ke_fallback_head->fallback_bound);
    216 
    217 	KSSL_COUNTER(proxy_fallback_failed, 1);
    218 
    219 	return (NULL);
    220 }
    221 
    222 /*
    223  * Re-usable code for adding and removing an element to/from a chain that
    224  * matches "item"
    225  * The chain is simple-linked and NULL ended.
    226  */
    227 
    228 /*
    229  * This routine returns TRUE if the item was either successfully added to
    230  * the chain, or is already there. It returns FALSE otherwise.
    231  */
    232 static boolean_t
    233 kssl_enqueue(kssl_chain_t **head, void *item)
    234 {
    235 	kssl_chain_t *newchain, *cur;
    236 
    237 	/* Lookup the existing entries to avoid duplicates */
    238 	cur = *head;
    239 	while (cur != NULL) {
    240 		if (cur->item == item) {
    241 			return (B_TRUE);
    242 		}
    243 		cur = cur->next;
    244 	}
    245 
    246 	newchain = kmem_alloc(sizeof (kssl_chain_t), KM_NOSLEEP);
    247 	if (newchain == NULL) {
    248 		return (B_FALSE);
    249 	}
    250 
    251 	newchain->item = item;
    252 	newchain->next = *head;
    253 	*head = newchain;
    254 	return (B_TRUE);
    255 }
    256 
    257 static void
    258 kssl_dequeue(kssl_chain_t **head, void *item)
    259 {
    260 	kssl_chain_t *prev, *cur;
    261 
    262 	prev = cur = *head;
    263 	while (cur != NULL) {
    264 		if (cur->item == item) {
    265 			if (cur == *head)
    266 				*head = (*head)->next;
    267 			else
    268 				prev->next = cur->next;
    269 			kmem_free(cur, sizeof (kssl_chain_t));
    270 			return;
    271 		}
    272 		prev = cur;
    273 		cur = cur->next;
    274 	}
    275 }
    276 
    277 /*
    278  * Holds the kssl_entry
    279  */
    280 void
    281 kssl_hold_ent(kssl_ent_t ksslent)
    282 {
    283 	KSSL_ENTRY_REFHOLD((kssl_entry_t *)ksslent);
    284 }
    285 
    286 /*
    287  * Releases the kssl_entry
    288  * If the caller passes a cookie, then it should be removed from both
    289  * proxies and fallbacks chains.
    290  */
    291 void
    292 kssl_release_ent(kssl_ent_t ksslent, void *cookie, kssl_endpt_type_t endpt_type)
    293 {
    294 	kssl_entry_t *kssl_entry = (kssl_entry_t *)ksslent;
    295 
    296 	if (cookie != NULL) {
    297 		if (endpt_type == KSSL_IS_PROXY) {
    298 			ASSERT(kssl_entry->ke_proxy_head != NULL);
    299 			kssl_dequeue(
    300 			    (kssl_chain_t **)&kssl_entry->ke_proxy_head,
    301 			    cookie);
    302 		}
    303 		if (endpt_type == KSSL_HAS_PROXY) {
    304 			ASSERT(kssl_entry->ke_fallback_head != NULL);
    305 			kssl_dequeue(
    306 			    (kssl_chain_t **)&kssl_entry->ke_fallback_head,
    307 			    cookie);
    308 		}
    309 	}
    310 	KSSL_ENTRY_REFRELE(kssl_entry);
    311 }
    312 
    313 /*
    314  * Holds the kssl context
    315  */
    316 void
    317 kssl_hold_ctx(kssl_ctx_t ksslctx)
    318 {
    319 	ssl_t *ssl = (ssl_t *)ksslctx;
    320 
    321 	KSSL_SSL_REFHOLD(ssl);
    322 }
    323 
    324 /*
    325  * Releases the kssl_context
    326  */
    327 void
    328 kssl_release_ctx(kssl_ctx_t ksslctx)
    329 {
    330 	KSSL_SSL_REFRELE((ssl_t *)ksslctx);
    331 }
    332 
    333 /*
    334  * Packets are accumulated here, if there are packets already queued,
    335  * or if the context is active.
    336  * The context is active when an incoming record processing function
    337  * is already executing on a different thread.
    338  * Queued packets are handled either when an mblk arrived and completes
    339  * a record, or, when the active context processor finishes the task at
    340  * hand.
    341  * The caller has to keep calling this routine in a loop until it returns
    342  * B_FALSE in *more. The reason for this is SSL3: The protocol
    343  * allows the client to send its first application_data message right
    344  * after it had sent its Finished message, and not wait for the server
    345  * ChangeCipherSpec and Finished. This overlap means we can't batch up
    346  * a returned Handshake message to be sent on the wire
    347  * with a decrypted application_data to be delivered to the application.
    348  */
    349 kssl_cmd_t
    350 kssl_input(kssl_ctx_t ctx, mblk_t *mp, mblk_t **decrmp, boolean_t *more,
    351     kssl_callback_t cbfn, void *arg)
    352 {
    353 	mblk_t *recmp, *outmp = NULL;
    354 	kssl_cmd_t kssl_cmd;
    355 	ssl_t *ssl;
    356 	uint8_t *rec_sz_p;
    357 	int mplen;
    358 	SSL3ContentType content_type;
    359 	uint16_t rec_sz;
    360 
    361 	ASSERT(ctx != NULL);
    362 
    363 	if (mp != NULL) {
    364 		ASSERT(mp->b_prev == NULL && mp->b_next == NULL);
    365 	}
    366 
    367 	ssl = (ssl_t *)(ctx);
    368 
    369 	*decrmp = NULL;
    370 	*more = B_FALSE;
    371 
    372 	mutex_enter(&ssl->kssl_lock);
    373 
    374 	if (ssl->close_notify == B_TRUE) {
    375 		DTRACE_PROBE(kssl_err__close_notify);
    376 		goto sendnewalert;
    377 	}
    378 
    379 	/* Whomever is currently processing this connection will get to this */
    380 	if (ssl->activeinput) {
    381 		if (mp != NULL) {
    382 			KSSL_ENQUEUE_MP(ssl, mp);
    383 		}
    384 		mutex_exit(&ssl->kssl_lock);
    385 		return (KSSL_CMD_NONE);
    386 	}
    387 
    388 	/*
    389 	 * Fast path for complete incoming application_data records on an empty
    390 	 * queue.
    391 	 * This is by far the most frequently encountered case
    392 	 */
    393 
    394 	if ((!ssl->activeinput) && (ssl->rec_ass_head == NULL) &&
    395 	    ((mp != NULL) && (mplen = MBLKL(mp)) > SSL3_HDR_LEN)) {
    396 
    397 		DTRACE_PROBE1(kssl_mblk__fast_path, mblk_t *, mp);
    398 		content_type = (SSL3ContentType)mp->b_rptr[0];
    399 
    400 		if ((content_type == content_application_data) &&
    401 		    (ssl->hs_waitstate == idle_handshake)) {
    402 			rec_sz_p = SSL3_REC_SIZE(mp);
    403 			rec_sz = BE16_TO_U16(rec_sz_p);
    404 
    405 			if ((mp->b_cont == NULL) && (mplen == rec_sz)) {
    406 
    407 				DB_FLAGS(mp) &= ~DBLK_COOKED;
    408 				*decrmp = mp;
    409 				mutex_exit(&ssl->kssl_lock);
    410 				return (KSSL_CMD_DELIVER_PROXY);
    411 			}
    412 		}
    413 	}
    414 
    415 	ssl->activeinput = B_TRUE;
    416 	/* Accumulate at least one record */
    417 	if (mp != NULL) {
    418 		KSSL_ENQUEUE_MP(ssl, mp);
    419 		mp = NULL;
    420 	}
    421 	recmp = kssl_get_next_record(ssl);
    422 
    423 	if (recmp == NULL) {
    424 		ssl->activeinput = B_FALSE;
    425 		if (ssl->alert_sendbuf != NULL) {
    426 			DTRACE_PROBE(kssl_err__alert_to_send);
    427 			goto sendalert;
    428 		}
    429 		/* Not even a complete header yet. wait for the rest */
    430 		mutex_exit(&ssl->kssl_lock);
    431 		return (KSSL_CMD_NONE);
    432 	}
    433 
    434 	do {
    435 		DTRACE_PROBE1(kssl_mblk__kssl_input_cycle, mblk_t *, recmp);
    436 		content_type = (SSL3ContentType)recmp->b_rptr[0];
    437 
    438 		switch (content_type) {
    439 		case content_application_data:
    440 			/*
    441 			 * application_data records are decrypted and
    442 			 * MAC-verified by the stream head, and in the context
    443 			 * a read()'ing thread. This avoids unfairly charging
    444 			 * the cost of handling this record on the whole system,
    445 			 * and prevents doing it while in the shared IP
    446 			 * perimeter.
    447 			 */
    448 			ssl->activeinput = B_FALSE;
    449 			if (ssl->hs_waitstate != idle_handshake) {
    450 				DTRACE_PROBE(kssl_err__waitstate_not_idle);
    451 				goto sendnewalert;
    452 			}
    453 			outmp = recmp;
    454 			kssl_cmd = KSSL_CMD_DELIVER_PROXY;
    455 			break;
    456 		case content_change_cipher_spec:
    457 		case content_alert:
    458 		case content_handshake:
    459 		case content_handshake_v2:
    460 			/*
    461 			 * If we're past the initial handshake, start letting
    462 			 * the stream head process all records, in particular
    463 			 * the close_notify.
    464 			 * This is needed to avoid processing them out of
    465 			 * sequence when previous application data packets are
    466 			 * waiting to be decrypted/MAC'ed and delivered.
    467 			 */
    468 			if (ssl->hs_waitstate == idle_handshake) {
    469 				ssl->activeinput = B_FALSE;
    470 				outmp = recmp;
    471 				kssl_cmd = KSSL_CMD_DELIVER_PROXY;
    472 			} else {
    473 				kssl_cmd = kssl_handle_any_record(ssl, recmp,
    474 				    &outmp, cbfn, arg);
    475 			}
    476 			break;
    477 		default:
    478 			ssl->activeinput = B_FALSE;
    479 			DTRACE_PROBE(kssl_err__invalid_content_type);
    480 			goto sendnewalert;
    481 		}
    482 
    483 		/* Priority to Alert messages */
    484 		if (ssl->alert_sendbuf != NULL) {
    485 			DTRACE_PROBE(kssl_err__alert_to_send_cycle);
    486 			goto sendalert;
    487 		}
    488 
    489 		/* Then handshake messages */
    490 		if (ssl->handshake_sendbuf) {
    491 			if (*decrmp != NULL) {
    492 				linkb(*decrmp, ssl->handshake_sendbuf);
    493 			} else {
    494 				*decrmp = ssl->handshake_sendbuf;
    495 			}
    496 			ssl->handshake_sendbuf = NULL;
    497 
    498 			*more = ((ssl->rec_ass_head != NULL) &&
    499 			    (!ssl->activeinput));
    500 			mutex_exit(&ssl->kssl_lock);
    501 			return (kssl_cmd);
    502 		}
    503 
    504 		if (ssl->hs_waitstate == idle_handshake) {
    505 			*more = ((ssl->rec_ass_head != NULL) &&
    506 			    (!ssl->activeinput));
    507 		}
    508 
    509 		if (outmp != NULL) {
    510 			*decrmp = outmp;
    511 			/*
    512 			 * Don't process any packet after an application_data.
    513 			 * We could well receive the close_notify which should
    514 			 * be handled separately.
    515 			 */
    516 			mutex_exit(&ssl->kssl_lock);
    517 			return (kssl_cmd);
    518 		}
    519 		/*
    520 		 * The current record isn't done yet. Don't start the next one
    521 		 */
    522 		if (ssl->activeinput) {
    523 			mutex_exit(&ssl->kssl_lock);
    524 			return (kssl_cmd);
    525 		}
    526 	} while ((recmp = kssl_get_next_record(ssl)) != NULL);
    527 
    528 	mutex_exit(&ssl->kssl_lock);
    529 	return (kssl_cmd);
    530 
    531 sendnewalert:
    532 	kssl_send_alert(ssl, alert_fatal, unexpected_message);
    533 	if (mp != NULL) {
    534 		freeb(mp);
    535 	}
    536 
    537 sendalert:
    538 	*decrmp = ssl->alert_sendbuf;
    539 	ssl->alert_sendbuf = NULL;
    540 	mutex_exit(&ssl->kssl_lock);
    541 	return (KSSL_CMD_SEND);
    542 }
    543 
    544 /*
    545  * Process mblk b_cont chain returned from stream head. The chain could
    546  * contain a mixture (albeit continuous) of processed and unprocessed
    547  * mblks. This situation could happen when more data was available in
    548  * stream head queue than requested. In such case the rest of processed
    549  * data would be putback().
    550  *
    551  * Processed mblks in this function contain either a full or partial portion
    552  * of a decrypted and verified SSL record. The former case is produced
    553  * by the function itself, the latter case is explained above.
    554  *
    555  * In case of unprocessed mblks, decrypt and verify the MAC of an incoming
    556  * chain of application_data record. Each block has exactly one SSL record.
    557  * This routine recycles incoming mblks, and flags them as DBLK_COOKED.
    558  */
    559 kssl_cmd_t
    560 kssl_handle_mblk(kssl_ctx_t ctx, mblk_t **mpp, mblk_t **outmp)
    561 {
    562 	uchar_t *recend, *rec_sz_p;
    563 	uchar_t *real_recend;
    564 	mblk_t *prevmp = NULL, *nextmp, *firstmp, *mp, *copybp;
    565 	int mac_sz;
    566 	uchar_t version[2];
    567 	uint16_t rec_sz;
    568 	SSL3AlertDescription desc;
    569 	SSL3ContentType content_type;
    570 	ssl_t *ssl;
    571 	KSSLCipherSpec *spec;
    572 	int error, ret;
    573 	kssl_cmd_t kssl_cmd = KSSL_CMD_DELIVER_PROXY;
    574 	boolean_t deliverit = B_FALSE;
    575 	crypto_data_t cipher_data;
    576 
    577 	ASSERT(ctx != NULL);
    578 
    579 	ssl = (ssl_t *)(ctx);
    580 
    581 	mp = firstmp = *mpp;
    582 	*outmp = NULL;
    583 
    584 	/*
    585 	 * Skip over already processed mblks. This prevents a case where
    586 	 * struiocopyout() copies unprocessed data to userland.
    587 	 */
    588 	while ((mp != NULL) && (DB_FLAGS(mp) & DBLK_COOKED)) {
    589 		ASSERT(DB_TYPE(mp) == M_DATA);
    590 		DTRACE_PROBE1(kssl_mblk__already_processed_mblk, mblk_t *, mp);
    591 		mp = mp->b_cont;
    592 	}
    593 
    594 more:
    595 
    596 	while (mp != NULL) {
    597 		/* only unprocessed mblks should reach us */
    598 		ASSERT(DB_TYPE(mp) == M_DATA);
    599 		ASSERT(!(DB_FLAGS(mp) & DBLK_COOKED));
    600 
    601 		if (DB_REF(mp) > 1) {
    602 			/*
    603 			 * Fortunately copyb() preserves the offset,
    604 			 * tail space and alignment so the copy is
    605 			 * ready to be made an SSL record.
    606 			 */
    607 			if ((copybp = copyb(mp)) == NULL)
    608 				return (NULL);
    609 
    610 			copybp->b_cont = mp->b_cont;
    611 			if (mp == firstmp) {
    612 				*mpp = copybp;
    613 			} else if (prevmp != NULL) {
    614 				prevmp->b_cont = copybp;
    615 			}
    616 			freeb(mp);
    617 			mp = copybp;
    618 		}
    619 
    620 		DTRACE_PROBE1(kssl_mblk__handle_record_cycle, mblk_t *, mp);
    621 		content_type = (SSL3ContentType)mp->b_rptr[0];
    622 
    623 		switch (content_type) {
    624 		case content_application_data:
    625 			break;
    626 		case content_change_cipher_spec:
    627 		case content_alert:
    628 		case content_handshake:
    629 		case content_handshake_v2:
    630 			nextmp = mp->b_cont;
    631 
    632 			/* Remove this message */
    633 			if (prevmp != NULL) {
    634 				prevmp->b_cont = nextmp;
    635 
    636 				/*
    637 				 * If we had processed blocks that need to
    638 				 * be delivered, then remember that error code
    639 				 */
    640 				if (kssl_cmd == KSSL_CMD_DELIVER_PROXY)
    641 					deliverit = B_TRUE;
    642 			}
    643 
    644 			mutex_enter(&ssl->kssl_lock);
    645 			/* NOTE: This routine could free mp. */
    646 			kssl_cmd = kssl_handle_any_record(ssl, mp, outmp,
    647 			    NULL, NULL);
    648 
    649 			if (ssl->alert_sendbuf != NULL) {
    650 				mp = nextmp;
    651 				DTRACE_PROBE(kssl_err__alert_after_handle_any);
    652 				goto sendalert;
    653 			}
    654 			mutex_exit(&ssl->kssl_lock);
    655 
    656 			if (deliverit) {
    657 				kssl_cmd = KSSL_CMD_DELIVER_PROXY;
    658 			}
    659 
    660 			mp = nextmp;
    661 			continue;	/* to the while loop */
    662 		default:
    663 			desc = decode_error;
    664 			KSSL_COUNTER(internal_errors, 1);
    665 			DTRACE_PROBE(kssl_err__decode_error);
    666 			goto makealert;
    667 		}
    668 
    669 		version[0] = mp->b_rptr[1];
    670 		version[1] = mp->b_rptr[2];
    671 		rec_sz_p = SSL3_REC_SIZE(mp);
    672 		rec_sz = BE16_TO_U16(rec_sz_p);
    673 
    674 		mp->b_rptr += SSL3_HDR_LEN;
    675 		recend = mp->b_rptr + rec_sz;
    676 		real_recend = recend;
    677 
    678 		/*
    679 		 * Check the assumption that each mblk contains exactly
    680 		 * one complete SSL record. We bail out if the check fails.
    681 		 */
    682 		ASSERT(recend == mp->b_wptr);
    683 		if (recend != mp->b_wptr) {
    684 			desc = decode_error;
    685 			KSSL_COUNTER(internal_errors, 1);
    686 			DTRACE_PROBE(kssl_err__not_complete_record);
    687 			goto makealert;
    688 		}
    689 
    690 		spec = &ssl->spec[KSSL_READ];
    691 		mac_sz = spec->mac_hashsz;
    692 		if (spec->cipher_ctx != 0) {
    693 
    694 			/*
    695 			 * The record length must be a multiple of the
    696 			 * block size for block ciphers.
    697 			 * The cipher_bsize is always a power of 2.
    698 			 */
    699 			if ((spec->cipher_type == type_block) &&
    700 			    ((rec_sz & (spec->cipher_bsize - 1)) != 0)) {
    701 				DTRACE_PROBE2(kssl_err__bad_record_size,
    702 				    uint16_t, rec_sz,
    703 				    int, spec->cipher_bsize);
    704 				KSSL_COUNTER(record_decrypt_failure, 1);
    705 				mp->b_rptr = recend;
    706 				desc = decrypt_error;
    707 				goto makealert;
    708 			}
    709 
    710 			cipher_data.cd_format = CRYPTO_DATA_RAW;
    711 			cipher_data.cd_offset = 0;
    712 			cipher_data.cd_length = rec_sz;
    713 			cipher_data.cd_miscdata = NULL;
    714 			cipher_data.cd_raw.iov_base = (char *)mp->b_rptr;
    715 			cipher_data.cd_raw.iov_len = rec_sz;
    716 			error = crypto_decrypt_update(spec->cipher_ctx,
    717 			    &cipher_data, NULL, NULL);
    718 			if (CRYPTO_ERR(error)) {
    719 				DTRACE_PROBE1(
    720 				    kssl_err__crypto_decrypt_update_failed,
    721 				    int, error);
    722 				KSSL_COUNTER(record_decrypt_failure, 1);
    723 				mp->b_rptr = recend;
    724 				desc = decrypt_error;
    725 				goto makealert;
    726 			}
    727 		}
    728 		if (spec->cipher_type == type_block) {
    729 			uint_t pad_sz = recend[-1];
    730 			pad_sz++;
    731 			if (pad_sz + mac_sz > rec_sz) {
    732 				DTRACE_PROBE(kssl_err__pad_mac_bigger);
    733 				mp->b_rptr = recend;
    734 				desc = bad_record_mac;
    735 				goto makealert;
    736 			}
    737 			rec_sz -= pad_sz;
    738 			recend -= pad_sz;
    739 		}
    740 		if (mac_sz != 0) {
    741 			uchar_t hash[MAX_HASH_LEN];
    742 			if (rec_sz < mac_sz) {
    743 				DTRACE_PROBE(kssl_err__pad_smaller_mac);
    744 				mp->b_rptr = real_recend;
    745 				desc = bad_record_mac;
    746 				goto makealert;
    747 			}
    748 			rec_sz -= mac_sz;
    749 			recend -= mac_sz;
    750 			ret = kssl_compute_record_mac(ssl, KSSL_READ,
    751 			    ssl->seq_num[KSSL_READ], content_type,
    752 			    version, mp->b_rptr, rec_sz, hash);
    753 			if (ret != CRYPTO_SUCCESS ||
    754 			    bcmp(hash, recend, mac_sz)) {
    755 				DTRACE_PROBE1(kssl_mblk__MACmismatch_handlerec,
    756 				    mblk_t *, mp);
    757 				mp->b_rptr = real_recend;
    758 				desc = bad_record_mac;
    759 				DTRACE_PROBE(kssl_err__msg_MAC_mismatch);
    760 				KSSL_COUNTER(verify_mac_failure, 1);
    761 				goto makealert;
    762 			}
    763 			ssl->seq_num[KSSL_READ]++;
    764 		}
    765 
    766 		if (ssl->hs_waitstate != idle_handshake) {
    767 			DTRACE_PROBE1(kssl_err__unexpected_msg,
    768 			    SSL3WaitState, ssl->hs_waitstate);
    769 			mp->b_rptr = real_recend;
    770 			desc = unexpected_message;
    771 			goto makealert;
    772 		}
    773 		mp->b_wptr = recend;
    774 
    775 		DB_FLAGS(mp) |= DBLK_COOKED;
    776 		DTRACE_PROBE1(kssl_mblk__dblk_cooked, mblk_t *, mp);
    777 		KSSL_COUNTER(appdata_record_ins, 1);
    778 
    779 		prevmp = mp;
    780 		mp = mp->b_cont;
    781 	}
    782 
    783 	return (kssl_cmd);
    784 
    785 makealert:
    786 	nextmp = mp->b_cont;
    787 	freeb(mp);
    788 	mp = nextmp;
    789 	mutex_enter(&ssl->kssl_lock);
    790 	kssl_send_alert(ssl, alert_fatal, desc);
    791 
    792 	if (ssl->alert_sendbuf == NULL) {
    793 		/* internal memory allocation failure. just return. */
    794 		DTRACE_PROBE(kssl_err__alert_msg_alloc_failed);
    795 		mutex_exit(&ssl->kssl_lock);
    796 
    797 		if (mp) {
    798 			prevmp = NULL;
    799 			goto more;
    800 		}
    801 
    802 		return (KSSL_CMD_NONE);
    803 	}
    804 	kssl_cmd = KSSL_CMD_SEND;
    805 sendalert:
    806 	if (*outmp == NULL) {
    807 		*outmp = ssl->alert_sendbuf;
    808 	} else {
    809 		linkb(*outmp, ssl->alert_sendbuf);
    810 	}
    811 	ssl->alert_sendbuf = NULL;
    812 	mutex_exit(&ssl->kssl_lock);
    813 
    814 	if (mp) {
    815 		prevmp = NULL;
    816 		goto more;
    817 	}
    818 
    819 	return (kssl_cmd);
    820 }
    821 /*
    822  * This is the routine that handles incoming SSL records.
    823  * When called the first time, with a NULL context, this routine expects
    824  * a ClientHello SSL Handshake packet and shall allocate a context
    825  * of a new SSL connection.
    826  * During the rest of the handshake packets, the routine adjusts the
    827  * state of the context according to the record received.
    828  * After the ChangeCipherSpec message is received, the routine first
    829  * decrypts/authenticated the packet using the key materials in the
    830  * connection's context.
    831  * The return code tells the caller what to do with the returned packet.
    832  */
    833 static kssl_cmd_t
    834 kssl_handle_any_record(kssl_ctx_t ctx, mblk_t *mp, mblk_t **decrmp,
    835     kssl_callback_t cbfn, void *arg)
    836 {
    837 	uchar_t *recend, *rec_sz_p;
    838 	uchar_t version[2];
    839 	uchar_t *real_recend, *save_rptr, *save_wptr;
    840 	int rhsz = SSL3_HDR_LEN;
    841 	uint16_t rec_sz;
    842 	int sz;
    843 	int mac_sz;
    844 	SSL3AlertDescription desc;
    845 	SSL3AlertLevel level;
    846 	SSL3ContentType content_type;
    847 	ssl_t *ssl;
    848 	KSSLCipherSpec *spec;
    849 	int error = 0, ret;
    850 
    851 	ASSERT(ctx != NULL);
    852 
    853 	ssl = (ssl_t *)(ctx);
    854 
    855 	*decrmp = NULL;
    856 
    857 	save_rptr = mp->b_rptr;
    858 	save_wptr = mp->b_wptr;
    859 
    860 	ASSERT(MUTEX_HELD(&ssl->kssl_lock));
    861 
    862 	content_type = (SSL3ContentType)mp->b_rptr[0];
    863 	if (content_type == content_handshake_v2) {
    864 		if (ssl->hs_waitstate == wait_client_hello) {
    865 			/* V2 compatible ClientHello */
    866 			if (mp->b_rptr[3] == 0x03 &&
    867 			    (mp->b_rptr[4] == 0x01 ||
    868 			    mp->b_rptr[4] == 0x00)) {
    869 				ssl->major_version = version[0] = mp->b_rptr[3];
    870 				ssl->minor_version = version[1] = mp->b_rptr[4];
    871 			} else {
    872 			/* We don't support "pure" SSLv2 */
    873 				DTRACE_PROBE(kssl_err__no_SSLv2);
    874 				desc = protocol_version;
    875 				goto sendalert;
    876 			}
    877 		}
    878 		rec_sz = (uint16_t)mp->b_rptr[1];
    879 		rhsz = 2;
    880 	} else {
    881 		ssl->major_version = version[0] = mp->b_rptr[1];
    882 		ssl->minor_version = version[1] = mp->b_rptr[2];
    883 		rec_sz_p = SSL3_REC_SIZE(mp);
    884 		rec_sz = BE16_TO_U16(rec_sz_p);
    885 	}
    886 
    887 	mp->b_rptr += rhsz;
    888 	recend = mp->b_rptr + rec_sz;
    889 	real_recend = recend;
    890 
    891 	/*
    892 	 * Check the assumption that each mblk contains exactly
    893 	 * one complete SSL record. We bail out if the check fails.
    894 	 */
    895 	ASSERT(recend == mp->b_wptr);
    896 	if (recend != mp->b_wptr) {
    897 		DTRACE_PROBE3(kssl_mblk__handle_any_record_recszerr,
    898 		    mblk_t *, mp, int, rhsz, int, rec_sz);
    899 		DTRACE_PROBE(kssl_err__record_size);
    900 		desc = decode_error;
    901 		KSSL_COUNTER(internal_errors, 1);
    902 		goto sendalert;
    903 	}
    904 
    905 	spec = &ssl->spec[KSSL_READ];
    906 	mac_sz = spec->mac_hashsz;
    907 	if (spec->cipher_ctx != 0) {
    908 		/*
    909 		 * The record length must be a multiple of the
    910 		 * block size for block ciphers.
    911 		 */
    912 		if ((spec->cipher_type == type_block) &&
    913 		    ((rec_sz & (spec->cipher_bsize - 1)) != 0)) {
    914 			DTRACE_PROBE2(kssl_err__bad_record_size,
    915 			    uint16_t, rec_sz, int, spec->cipher_bsize);
    916 			KSSL_COUNTER(record_decrypt_failure, 1);
    917 			mp->b_rptr = recend;
    918 			desc = decrypt_error;
    919 			goto sendalert;
    920 		}
    921 
    922 		spec->cipher_data.cd_length = rec_sz;
    923 		spec->cipher_data.cd_raw.iov_base = (char *)mp->b_rptr;
    924 		spec->cipher_data.cd_raw.iov_len = rec_sz;
    925 		error = crypto_decrypt_update(spec->cipher_ctx,
    926 		    &spec->cipher_data, NULL, NULL);
    927 		if (CRYPTO_ERR(error)) {
    928 			DTRACE_PROBE1(kssl_err__crypto_decrypt_update_failed,
    929 			    int, error);
    930 			KSSL_COUNTER(record_decrypt_failure, 1);
    931 			mp->b_rptr = recend;
    932 			desc = decrypt_error;
    933 			goto sendalert;
    934 		}
    935 	}
    936 	if (spec->cipher_type == type_block) {
    937 		uint_t pad_sz = recend[-1];
    938 		pad_sz++;
    939 		if (pad_sz + mac_sz > rec_sz) {
    940 			DTRACE_PROBE2(kssl_err__pad_mac_mismatch,
    941 			    int, pad_sz, int, mac_sz);
    942 			mp->b_rptr = recend;
    943 			desc = bad_record_mac;
    944 			goto sendalert;
    945 		}
    946 		rec_sz -= pad_sz;
    947 		recend -= pad_sz;
    948 	}
    949 	if (mac_sz != 0) {
    950 		uchar_t hash[MAX_HASH_LEN];
    951 		if (rec_sz < mac_sz) {
    952 			DTRACE_PROBE1(kssl_err__mac_size_too_big,
    953 			    int, mac_sz);
    954 			mp->b_rptr = real_recend;
    955 			desc = bad_record_mac;
    956 			goto sendalert;
    957 		}
    958 		rec_sz -= mac_sz;
    959 		recend -= mac_sz;
    960 		ret = kssl_compute_record_mac(ssl, KSSL_READ,
    961 		    ssl->seq_num[KSSL_READ], content_type,
    962 		    version, mp->b_rptr, rec_sz, hash);
    963 		if (ret != CRYPTO_SUCCESS ||
    964 		    bcmp(hash, recend, mac_sz)) {
    965 			DTRACE_PROBE1(kssl_mblk__MACmismatch_anyrecord,
    966 			    mblk_t *, mp);
    967 			mp->b_rptr = real_recend;
    968 			desc = bad_record_mac;
    969 			DTRACE_PROBE(kssl_err__msg_MAC_mismatch);
    970 			KSSL_COUNTER(verify_mac_failure, 1);
    971 			goto sendalert;
    972 		}
    973 		ssl->seq_num[KSSL_READ]++;
    974 		DTRACE_PROBE1(kssl_mblk__after_compute_MAC,
    975 		    mblk_t *, mp);
    976 	}
    977 
    978 	switch (content_type) {
    979 	case content_handshake:
    980 		do {
    981 			DTRACE_PROBE1(kssl_mblk__content_handshake_cycle,
    982 			    mblk_t *, mp);
    983 			if (error != 0 ||
    984 			    /* ignore client renegotiation for now */
    985 			    ssl->hs_waitstate == idle_handshake) {
    986 				mp->b_rptr = recend;
    987 			}
    988 			if (mp->b_rptr == recend) {
    989 				mp->b_rptr = real_recend;
    990 				if (error != 0) {
    991 					goto error;
    992 				}
    993 				freeb(mp);
    994 
    995 				if (ssl->hs_waitstate == wait_client_key_done)
    996 					return (KSSL_CMD_QUEUED);
    997 
    998 				return ((ssl->handshake_sendbuf != NULL) ?
    999 				    KSSL_CMD_SEND : KSSL_CMD_NONE);
   1000 			}
   1001 			if (ssl->msg.state < MSG_BODY) {
   1002 				if (ssl->msg.state == MSG_INIT) {
   1003 					ssl->msg.type =
   1004 					    (SSL3HandshakeType)*mp->b_rptr++;
   1005 					ssl->msg.state = MSG_INIT_LEN;
   1006 				}
   1007 				if (ssl->msg.state == MSG_INIT_LEN) {
   1008 					int msglenb =
   1009 					    ssl->msg.msglen_bytes;
   1010 					int msglen = ssl->msg.msglen;
   1011 					while (mp->b_rptr < recend &&
   1012 					    msglenb < 3) {
   1013 						msglen = (msglen << 8) +
   1014 						    (uint_t)(*mp->b_rptr++);
   1015 						msglenb++;
   1016 					}
   1017 					ssl->msg.msglen_bytes = msglenb;
   1018 					ssl->msg.msglen = msglen;
   1019 					if (msglenb == 3) {
   1020 						ssl->msg.state = MSG_BODY;
   1021 					}
   1022 				}
   1023 				if (mp->b_rptr == recend) {
   1024 					mp->b_rptr = real_recend;
   1025 					freeb(mp);
   1026 					return (KSSL_CMD_NONE);
   1027 				}
   1028 			}
   1029 			ASSERT(ssl->msg.state == MSG_BODY);
   1030 
   1031 			sz = recend - mp->b_rptr;
   1032 
   1033 			if (ssl->msg.head == NULL &&
   1034 			    ssl->msg.msglen <= sz) {
   1035 				continue;
   1036 			}
   1037 			if (ssl->msg.head != NULL) {
   1038 				sz += msgdsize(ssl->msg.head);
   1039 				if (ssl->msg.msglen <= sz) {
   1040 					ssl->msg.tail->b_cont = mp;
   1041 					mp = ssl->msg.head;
   1042 					ssl->sslcnt = 100;
   1043 					ssl->msg.head = NULL;
   1044 					ssl->msg.tail = NULL;
   1045 					if (pullupmsg(mp, -1)) {
   1046 						recend = mp->b_rptr + sz;
   1047 						ASSERT(recend <= mp->b_wptr);
   1048 						continue;
   1049 					}
   1050 					mp->b_rptr = real_recend;
   1051 					error = ENOMEM;
   1052 					KSSL_COUNTER(alloc_fails, 1);
   1053 					goto error;
   1054 				}
   1055 			}
   1056 
   1057 			mp->b_wptr = recend;
   1058 
   1059 			if (ssl->msg.head == NULL) {
   1060 				ssl->msg.head = mp;
   1061 				ssl->msg.tail = mp;
   1062 				return (KSSL_CMD_NONE);
   1063 			} else {
   1064 				ssl->msg.tail->b_cont = mp;
   1065 				ssl->msg.tail = mp;
   1066 				return (KSSL_CMD_NONE);
   1067 			}
   1068 		} while (kssl_handle_handshake_message(ssl, mp, &error, cbfn,
   1069 		    arg));
   1070 		if (error == SSL_MISS) {
   1071 			mp->b_rptr = save_rptr;
   1072 			mp->b_wptr = save_wptr;
   1073 			KSSL_COUNTER(fallback_connections, 1);
   1074 			return (KSSL_CMD_NOT_SUPPORTED);
   1075 		}
   1076 		if (ssl->hs_waitstate == wait_client_key_done) {
   1077 			return (KSSL_CMD_QUEUED);
   1078 		} else {
   1079 			return (KSSL_CMD_NONE);
   1080 		}
   1081 	case content_alert:
   1082 		DTRACE_PROBE1(kssl_mblk__content_alert, mblk_t *, mp);
   1083 		if (rec_sz != 2) {
   1084 			DTRACE_PROBE(kssl_err__illegal_param);
   1085 			mp->b_rptr = real_recend;
   1086 			desc = illegal_parameter;
   1087 			goto sendalert;
   1088 		} else {
   1089 			level = *mp->b_rptr++;
   1090 			desc = *mp->b_rptr++;
   1091 			mp->b_rptr = real_recend;
   1092 			if (level != alert_warning || desc != close_notify) {
   1093 				if (ssl->sid.cached == B_TRUE) {
   1094 					kssl_uncache_sid(&ssl->sid,
   1095 					    ssl->kssl_entry);
   1096 				}
   1097 				DTRACE_PROBE2(kssl_err__bad_content_alert,
   1098 				    SSL3AlertLevel, level,
   1099 				    SSL3AlertDescription, desc);
   1100 				ssl->fatal_alert = B_TRUE;
   1101 				error = EBADMSG;
   1102 				goto error;
   1103 			} else {
   1104 				ssl->close_notify = B_TRUE;
   1105 				ssl->activeinput = B_FALSE;
   1106 				freeb(mp);
   1107 				return (KSSL_CMD_NONE);
   1108 			}
   1109 		}
   1110 	case content_change_cipher_spec:
   1111 		DTRACE_PROBE1(kssl_mblk__change_cipher_spec,
   1112 		    mblk_t *, mp);
   1113 		if (ssl->hs_waitstate != wait_change_cipher) {
   1114 			desc = unexpected_message;
   1115 		} else if (rec_sz != 1 || *mp->b_rptr != 1) {
   1116 			desc = illegal_parameter;
   1117 		} else {
   1118 			mp->b_rptr = real_recend;
   1119 			ssl->hs_waitstate = wait_finished;
   1120 			ssl->seq_num[KSSL_READ] = 0;
   1121 			if ((error = kssl_spec_init(ssl, KSSL_READ)) != 0) {
   1122 				DTRACE_PROBE1(kssl_err__kssl_spec_init_error,
   1123 				    int, error);
   1124 				goto error;
   1125 			}
   1126 			ssl->activeinput = B_FALSE;
   1127 			freeb(mp);
   1128 			return (KSSL_CMD_NONE);
   1129 		}
   1130 		mp->b_rptr = real_recend;
   1131 		DTRACE_PROBE(kssl_err__change_cipher_spec);
   1132 		goto sendalert;
   1133 
   1134 	case content_application_data:
   1135 		DTRACE_PROBE1(kssl_mblk__content_app_data,
   1136 		    mblk_t *, mp);
   1137 		if (ssl->hs_waitstate != idle_handshake) {
   1138 			DTRACE_PROBE(kssl_err__content_app_data);
   1139 			mp->b_rptr = real_recend;
   1140 			desc = unexpected_message;
   1141 			goto sendalert;
   1142 		}
   1143 		mp->b_wptr = recend;
   1144 		*decrmp = mp;
   1145 		ssl->activeinput = B_FALSE;
   1146 		return (KSSL_CMD_DELIVER_PROXY);
   1147 
   1148 	case content_handshake_v2:
   1149 		DTRACE_PROBE1(kssl_mblk__content_handshake_v2,
   1150 		    mblk_t *, mp);
   1151 		error = kssl_handle_v2client_hello(ssl, mp, rec_sz);
   1152 		if (error == SSL_MISS) {
   1153 			mp->b_rptr = save_rptr;
   1154 			mp->b_wptr = save_wptr;
   1155 			KSSL_COUNTER(fallback_connections, 1);
   1156 			return (KSSL_CMD_NOT_SUPPORTED);
   1157 		} else if (error != 0) {
   1158 			DTRACE_PROBE(kssl_err__v2client_hello_failed);
   1159 			goto error;
   1160 		}
   1161 		freeb(mp);
   1162 		return (KSSL_CMD_SEND);
   1163 	default:
   1164 		DTRACE_PROBE1(kssl_mblk__unexpected_msg,
   1165 		    mblk_t *, mp);
   1166 		mp->b_rptr = real_recend;
   1167 		desc = unexpected_message;
   1168 		break;
   1169 	}
   1170 
   1171 sendalert:
   1172 	kssl_send_alert(ssl, alert_fatal, desc);
   1173 	*decrmp = ssl->alert_sendbuf;
   1174 	ssl->alert_sendbuf = NULL;
   1175 	freeb(mp);
   1176 	return ((*decrmp != NULL) ? KSSL_CMD_SEND : KSSL_CMD_NONE);
   1177 error:
   1178 	freeb(mp);
   1179 	return (KSSL_CMD_NONE);
   1180 }
   1181 
   1182 /*
   1183  * Initialize the context of an SSL connection, coming to the specified
   1184  * address. The ssl structure is returned held.
   1185  */
   1186 kssl_status_t
   1187 kssl_init_context(kssl_ent_t kssl_ent, void *addr, boolean_t is_v4,
   1188     int mss, kssl_ctx_t *kssl_ctxp)
   1189 {
   1190 	ssl_t *ssl = kmem_cache_alloc(kssl_cache, KM_NOSLEEP);
   1191 
   1192 	if (ssl == NULL) {
   1193 		return (KSSL_STS_ERR);
   1194 	}
   1195 
   1196 	kssl_cache_count++;
   1197 
   1198 	bzero(ssl, sizeof (ssl_t));
   1199 
   1200 	ssl->kssl_entry = (kssl_entry_t *)kssl_ent;
   1201 	KSSL_ENTRY_REFHOLD(ssl->kssl_entry);
   1202 
   1203 	if (is_v4) {
   1204 		IN6_IPADDR_TO_V4MAPPED(*((ipaddr_t *)addr), &ssl->faddr);
   1205 	} else {
   1206 		ssl->faddr = *((in6_addr_t *)addr);	/* struct assignment */
   1207 	}
   1208 	ssl->tcp_mss = mss;
   1209 	ssl->sendalert_level = alert_warning;
   1210 	ssl->sendalert_desc = close_notify;
   1211 	ssl->sid.cached = B_FALSE;
   1212 
   1213 	*kssl_ctxp = (kssl_ctx_t)ssl;
   1214 	KSSL_SSL_REFHOLD(ssl);
   1215 	return (KSSL_STS_OK);
   1216 }
   1217 
   1218 /*
   1219  * Builds SSL records out of the chain of mblks, and returns it.
   1220  * Takes a copy of the message before encrypting it if it has another
   1221  * reference.
   1222  * In case of failure, NULL is returned, and the message will be
   1223  * freed by the caller.
   1224  * A NULL mp means a close_notify is requested.
   1225  */
   1226 mblk_t *
   1227 kssl_build_record(kssl_ctx_t ctx, mblk_t *mp)
   1228 {
   1229 	ssl_t *ssl = (ssl_t *)ctx;
   1230 	mblk_t *retmp = mp, *bp = mp, *prevbp = mp, *copybp;
   1231 
   1232 	ASSERT(ssl != NULL);
   1233 	ASSERT(mp != NULL);
   1234 
   1235 	do {
   1236 		if (DB_REF(bp) > 1) {
   1237 			/*
   1238 			 * Fortunately copyb() preserves the offset,
   1239 			 * tail space and alignment so the copy is
   1240 			 * ready to be made an SSL record.
   1241 			 */
   1242 			if ((copybp = copyb(bp)) == NULL)
   1243 				return (NULL);
   1244 
   1245 			copybp->b_cont = bp->b_cont;
   1246 			if (bp == mp) {
   1247 				retmp = copybp;
   1248 			} else {
   1249 				prevbp->b_cont = copybp;
   1250 			}
   1251 			freeb(bp);
   1252 			bp = copybp;
   1253 		}
   1254 
   1255 		if (kssl_build_single_record(ssl, bp) != KSSL_STS_OK)
   1256 			return (NULL);
   1257 
   1258 		prevbp = bp;
   1259 		bp = bp->b_cont;
   1260 	} while (bp != NULL);
   1261 
   1262 	return (retmp);
   1263 }
   1264 
   1265 /*
   1266  * Builds a single SSL record.
   1267  * In-line encryption of the record.
   1268  */
   1269 static kssl_status_t
   1270 kssl_build_single_record(ssl_t *ssl, mblk_t *mp)
   1271 {
   1272 	int len;
   1273 	int reclen;
   1274 	uchar_t *recstart, *versionp;
   1275 	KSSLCipherSpec *spec;
   1276 	int mac_sz;
   1277 	int pad_sz;
   1278 
   1279 	spec = &ssl->spec[KSSL_WRITE];
   1280 	mac_sz = spec->mac_hashsz;
   1281 
   1282 	ASSERT(DB_REF(mp) == 1);
   1283 	ASSERT((mp->b_rptr - mp->b_datap->db_base >= SSL3_HDR_LEN) &&
   1284 	    (mp->b_datap->db_lim - mp->b_wptr >= mac_sz + spec->cipher_bsize));
   1285 
   1286 	len = MBLKL(mp);
   1287 
   1288 	ASSERT(len > 0);
   1289 
   1290 	mutex_enter(&ssl->kssl_lock);
   1291 
   1292 	recstart = mp->b_rptr = mp->b_rptr - SSL3_HDR_LEN;
   1293 	recstart[0] = content_application_data;
   1294 	recstart[1] = ssl->major_version;
   1295 	recstart[2] = ssl->minor_version;
   1296 	versionp = &recstart[1];
   1297 
   1298 	reclen = len + mac_sz;
   1299 	if (spec->cipher_type == type_block) {
   1300 		pad_sz = spec->cipher_bsize -
   1301 		    (reclen & (spec->cipher_bsize - 1));
   1302 		ASSERT(reclen + pad_sz <=
   1303 		    SSL3_MAX_RECORD_LENGTH);
   1304 		reclen += pad_sz;
   1305 	}
   1306 	recstart[3] = (reclen >> 8) & 0xff;
   1307 	recstart[4] = reclen & 0xff;
   1308 
   1309 	if (kssl_mac_encrypt_record(ssl, content_application_data, versionp,
   1310 	    recstart, mp) != 0) {
   1311 		/* Do we need an internal_error Alert here? */
   1312 		mutex_exit(&ssl->kssl_lock);
   1313 		return (KSSL_STS_ERR);
   1314 	}
   1315 
   1316 	KSSL_COUNTER(appdata_record_outs, 1);
   1317 	mutex_exit(&ssl->kssl_lock);
   1318 	return (KSSL_STS_OK);
   1319 }
   1320