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