xref: /titanic_44/usr/src/uts/common/inet/kssl/ksslapi.c (revision 269e59f9a28bf47e0f463e64fc5af4a408b73b21)
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 				desc = protocol_version;
874 				goto sendalert;
875 			}
876 		}
877 		rec_sz = (uint16_t)mp->b_rptr[1];
878 		rhsz = 2;
879 	} else {
880 		ssl->major_version = version[0] = mp->b_rptr[1];
881 		ssl->minor_version = version[1] = mp->b_rptr[2];
882 		rec_sz_p = SSL3_REC_SIZE(mp);
883 		rec_sz = BE16_TO_U16(rec_sz_p);
884 	}
885 
886 	mp->b_rptr += rhsz;
887 	recend = mp->b_rptr + rec_sz;
888 	real_recend = recend;
889 
890 	/*
891 	 * Check the assumption that each mblk contains exactly
892 	 * one complete SSL record. We bail out if the check fails.
893 	 */
894 	ASSERT(recend == mp->b_wptr);
895 	if (recend != mp->b_wptr) {
896 		DTRACE_PROBE3(kssl_mblk__handle_any_record_recszerr,
897 		    mblk_t *, mp, int, rhsz, int, rec_sz);
898 		DTRACE_PROBE(kssl_err__record_size);
899 		desc = decode_error;
900 		KSSL_COUNTER(internal_errors, 1);
901 		goto sendalert;
902 	}
903 
904 	spec = &ssl->spec[KSSL_READ];
905 	mac_sz = spec->mac_hashsz;
906 	if (spec->cipher_ctx != 0) {
907 		/*
908 		 * The record length must be a multiple of the
909 		 * block size for block ciphers.
910 		 */
911 		if ((spec->cipher_type == type_block) &&
912 		    ((rec_sz & (spec->cipher_bsize - 1)) != 0)) {
913 			DTRACE_PROBE2(kssl_err__bad_record_size,
914 			    uint16_t, rec_sz, int, spec->cipher_bsize);
915 			KSSL_COUNTER(record_decrypt_failure, 1);
916 			mp->b_rptr = recend;
917 			desc = decrypt_error;
918 			goto sendalert;
919 		}
920 
921 		spec->cipher_data.cd_length = rec_sz;
922 		spec->cipher_data.cd_raw.iov_base = (char *)mp->b_rptr;
923 		spec->cipher_data.cd_raw.iov_len = rec_sz;
924 		error = crypto_decrypt_update(spec->cipher_ctx,
925 		    &spec->cipher_data, NULL, NULL);
926 		if (CRYPTO_ERR(error)) {
927 			DTRACE_PROBE1(kssl_err__crypto_decrypt_update_failed,
928 			    int, error);
929 			KSSL_COUNTER(record_decrypt_failure, 1);
930 			mp->b_rptr = recend;
931 			desc = decrypt_error;
932 			goto sendalert;
933 		}
934 	}
935 	if (spec->cipher_type == type_block) {
936 		uint_t pad_sz = recend[-1];
937 		pad_sz++;
938 		if (pad_sz + mac_sz > rec_sz) {
939 			DTRACE_PROBE2(kssl_err__pad_mac_mismatch,
940 			    int, pad_sz, int, mac_sz);
941 			mp->b_rptr = recend;
942 			desc = bad_record_mac;
943 			goto sendalert;
944 		}
945 		rec_sz -= pad_sz;
946 		recend -= pad_sz;
947 	}
948 	if (mac_sz != 0) {
949 		uchar_t hash[MAX_HASH_LEN];
950 		if (rec_sz < mac_sz) {
951 			DTRACE_PROBE1(kssl_err__mac_size_too_big,
952 			    int, mac_sz);
953 			mp->b_rptr = real_recend;
954 			desc = bad_record_mac;
955 			goto sendalert;
956 		}
957 		rec_sz -= mac_sz;
958 		recend -= mac_sz;
959 		ret = kssl_compute_record_mac(ssl, KSSL_READ,
960 		    ssl->seq_num[KSSL_READ], content_type,
961 		    version, mp->b_rptr, rec_sz, hash);
962 		if (ret != CRYPTO_SUCCESS ||
963 		    bcmp(hash, recend, mac_sz)) {
964 			DTRACE_PROBE1(kssl_mblk__MACmismatch_anyrecord,
965 			    mblk_t *, mp);
966 			mp->b_rptr = real_recend;
967 			desc = bad_record_mac;
968 			DTRACE_PROBE(kssl_err__msg_MAC_mismatch);
969 			KSSL_COUNTER(verify_mac_failure, 1);
970 			goto sendalert;
971 		}
972 		ssl->seq_num[KSSL_READ]++;
973 		DTRACE_PROBE1(kssl_mblk__after_compute_MAC,
974 		    mblk_t *, mp);
975 	}
976 
977 	switch (content_type) {
978 	case content_handshake:
979 		do {
980 			DTRACE_PROBE1(kssl_mblk__content_handshake_cycle,
981 			    mblk_t *, mp);
982 			if (error != 0 ||
983 			    /* ignore client renegotiation for now */
984 			    ssl->hs_waitstate == idle_handshake) {
985 				mp->b_rptr = recend;
986 				DTRACE_PROBE(kssl_renegotiation_request);
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