xref: /titanic_41/usr/src/uts/common/inet/kssl/ksslapi.c (revision 88f8b78a88cbdc6d8c1af5c3e54bc49d25095c98)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <sys/types.h>
30 #include <sys/stream.h>
31 #include <sys/strsun.h>
32 #include <sys/cmn_err.h>
33 #include <sys/kmem.h>
34 #include <sys/cpuvar.h>
35 #include <sys/atomic.h>
36 #include <sys/sysmacros.h>
37 
38 #include <inet/common.h>
39 #include <inet/ip.h>
40 #include <inet/ip6.h>
41 
42 #include <sys/systm.h>
43 #include <sys/param.h>
44 #include <sys/tihdr.h>
45 
46 #include "ksslimpl.h"
47 #include "ksslproto.h"
48 #include "ksslapi.h"
49 
50 static kssl_cmd_t kssl_handle_any_record(kssl_ctx_t ctx, mblk_t *mp,
51     mblk_t **decrmp, kssl_callback_t cbfn, void *arg);
52 static boolean_t kssl_enqueue(kssl_chain_t **head, void *item);
53 static void kssl_dequeue(kssl_chain_t **head, void *item);
54 static kssl_status_t kssl_build_single_record(ssl_t *ssl, mblk_t *mp);
55 
56 /*
57  * The socket T_bind_req message is intercepted and re-routed here
58  * to see is there is SSL relevant job to do, based on the kssl config
59  * in the kssl_entry_tab.
60  * Looks up the kernel SSL proxy table, to find an entry that matches the
61  * same serveraddr, and has one of the following two criteria:
62  * 1. in_port is an ssl_port. This endpoint can be used later as a fallback
63  *    to complete connections that cannot be handled by the SSL kernel proxy
64  *    (typically non supported ciphersuite). The cookie for the calling client
65  *    is saved with the kssl_entry to be retrieved for the fallback.
66  *    The function returns KSSL_HAS_PROXY.
67  *
68  * 2. in_port is a proxy port for another ssl port. The ssl port is then
69  *    substituted to the in_port in the bind_req TPI structure, so that
70  *    the bind falls through to the SSL port. At the end of this operation,
71  *    all the packets arriving to the SSL port will be delivered to an
72  *    accepted endpoint child of this bound socket.
73  *    The  kssl_entry_t is returned in *ksslent, for later use by the
74  *    lower modules' SSL hooks that handle the Handshake messages.
75  *    The function returns KSSL_IS_PROXY.
76  *
77  * The function returns KSSL_NO_PROXY otherwise. We do not suppport
78  * IPv6 addresses.
79  */
80 
81 kssl_endpt_type_t
82 kssl_check_proxy(mblk_t *bindmp, void *cookie, kssl_ent_t *ksslent)
83 {
84 	int i;
85 	kssl_endpt_type_t ret;
86 	kssl_entry_t *ep;
87 	sin_t *sin;
88 	struct T_bind_req *tbr;
89 	ipaddr_t v4addr;
90 	in_port_t in_port;
91 
92 	if (kssl_enabled == 0) {
93 		return (KSSL_NO_PROXY);
94 	}
95 
96 	tbr = (struct T_bind_req *)bindmp->b_rptr;
97 
98 	ret = KSSL_NO_PROXY;
99 
100 
101 	switch (tbr->ADDR_length) {
102 	case sizeof (sin_t):
103 		sin = (sin_t *)(bindmp->b_rptr + tbr->ADDR_length);
104 		in_port = ntohs(sin->sin_port);
105 		v4addr = sin->sin_addr.s_addr;
106 		break;
107 
108 	case sizeof (sin6_t):
109 		/* Future support of IPv6 goes here */
110 	default:
111 		/* Should ASSERT() here? */
112 		return (ret);
113 	}
114 
115 	mutex_enter(&kssl_tab_mutex);
116 
117 	for (i = 0; i < kssl_entry_tab_size; i++) {
118 		if ((ep = kssl_entry_tab[i]) == NULL)
119 			continue;
120 
121 		if ((ep->ke_laddr == v4addr) || (ep->ke_laddr == INADDR_ANY)) {
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 		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 	KSSL_ENTRY_REFRELE(kssl_entry);
309 }
310 
311 /*
312  * Holds the kssl context
313  */
314 void
315 kssl_hold_ctx(kssl_ctx_t ksslctx)
316 {
317 	ssl_t *ssl = (ssl_t *)ksslctx;
318 
319 	KSSL_SSL_REFHOLD(ssl);
320 }
321 
322 /*
323  * Releases the kssl_context
324  */
325 void
326 kssl_release_ctx(kssl_ctx_t ksslctx)
327 {
328 	KSSL_SSL_REFRELE((ssl_t *)ksslctx);
329 }
330 
331 /*
332  * Packets are accumulated here, if there are packets already queued,
333  * or if the context is active.
334  * The context is active when an incoming record processing function
335  * is already executing on a different thread.
336  * Queued packets are handled either when an mblk arrived and completes
337  * a record, or, when the active context processor finishes the task at
338  * hand.
339  * The caller has to keep calling this routine in a loop until it returns
340  * B_FALSE in *more. The reason for this is SSL3: The protocol
341  * allows the client to send its first application_data message right
342  * after it had sent its Finished message, and not wait for the server
343  * ChangeCipherSpec and Finished. This overlap means we can't batch up
344  * a returned Handshake message to be sent on the wire
345  * with a decrypted application_data to be delivered to the application.
346  */
347 kssl_cmd_t
348 kssl_input(kssl_ctx_t ctx, mblk_t *mp, mblk_t **decrmp, boolean_t *more,
349     kssl_callback_t cbfn, void *arg)
350 {
351 	mblk_t *recmp, *outmp = NULL;
352 	kssl_cmd_t kssl_cmd;
353 	ssl_t *ssl;
354 	uint8_t *rec_sz_p;
355 	int mplen;
356 	SSL3ContentType content_type;
357 	uint16_t rec_sz;
358 
359 	ASSERT(ctx != NULL);
360 
361 	if (mp != NULL) {
362 		ASSERT(mp->b_prev == NULL && mp->b_next == NULL);
363 	}
364 
365 	ssl = (ssl_t *)(ctx);
366 
367 	*decrmp = NULL;
368 	*more = B_FALSE;
369 
370 	mutex_enter(&ssl->kssl_lock);
371 
372 	if (ssl->close_notify == B_TRUE) {
373 		goto sendnewalert;
374 	}
375 
376 	/* Whomever is currently processing this connection will get to this */
377 	if (ssl->activeinput) {
378 		if (mp != NULL) {
379 			KSSL_ENQUEUE_MP(ssl, mp);
380 		}
381 		mutex_exit(&ssl->kssl_lock);
382 		return (KSSL_CMD_NONE);
383 	}
384 
385 	/*
386 	 * Fast path for complete incoming application_data records on an empty
387 	 * queue.
388 	 * This is by far the most frequently encountered case
389 	 */
390 
391 	if ((!ssl->activeinput) && (ssl->rec_ass_head == NULL) &&
392 	    ((mp != NULL) && (mplen = MBLKL(mp)) > SSL3_HDR_LEN)) {
393 
394 		content_type = (SSL3ContentType)mp->b_rptr[0];
395 
396 		if ((content_type == content_application_data) &&
397 		    (ssl->hs_waitstate == idle_handshake)) {
398 			rec_sz_p = SSL3_REC_SIZE(mp);
399 			rec_sz = BE16_TO_U16(rec_sz_p);
400 
401 			if ((mp->b_cont == NULL) && (mplen == rec_sz)) {
402 
403 				mp->b_flag &= ~DBLK_COOKED;
404 				*decrmp = mp;
405 				mutex_exit(&ssl->kssl_lock);
406 				return (KSSL_CMD_DELIVER_PROXY);
407 			}
408 		}
409 	}
410 
411 	ssl->activeinput = B_TRUE;
412 	/* Accumulate at least one record */
413 	if (mp != NULL) {
414 		KSSL_ENQUEUE_MP(ssl, mp);
415 		mp = NULL;
416 	}
417 	recmp = kssl_get_next_record(ssl);
418 
419 	if (recmp == NULL) {
420 		ssl->activeinput = B_FALSE;
421 		if (ssl->alert_sendbuf != NULL) {
422 			goto sendalert;
423 		}
424 		/* Not even a complete header yet. wait for the rest */
425 		mutex_exit(&ssl->kssl_lock);
426 		return (KSSL_CMD_NONE);
427 	}
428 
429 	do {
430 		if ((SSL3ContentType)recmp->b_rptr[0] ==
431 		    content_application_data) {
432 			/*
433 			 * application_data records are decrypted and
434 			 * MAC-verified by the stream head, and in the context
435 			 * a read()'ing thread. This avoids unfairly charging
436 			 * the cost of handling this record on the whole system,
437 			 * and prevents doing it while in the shared IP
438 			 * perimeter.
439 			 */
440 			ssl->activeinput = B_FALSE;
441 			if (ssl->hs_waitstate != idle_handshake) {
442 				goto sendnewalert;
443 			}
444 			outmp = recmp;
445 			kssl_cmd = KSSL_CMD_DELIVER_PROXY;
446 		} else {
447 			/*
448 			 * If we're past the initial handshake, start letting
449 			 * the stream head process all records, in particular
450 			 * the close_notify.
451 			 * This is needed to avoid processing them out of
452 			 * sequence when previous application data packets are
453 			 * waiting to be decrypted/MAC'ed and delivered.
454 			 */
455 			if (ssl->hs_waitstate == idle_handshake) {
456 				ssl->activeinput = B_FALSE;
457 				outmp = recmp;
458 				kssl_cmd = KSSL_CMD_DELIVER_PROXY;
459 			} else {
460 				kssl_cmd = kssl_handle_any_record(ssl, recmp,
461 				    &outmp, cbfn, arg);
462 			}
463 		}
464 
465 		/* Priority to Alert messages */
466 		if (ssl->alert_sendbuf != NULL) {
467 			goto sendalert;
468 		}
469 
470 		/* Then handshake messages */
471 		if (ssl->handshake_sendbuf) {
472 			if (*decrmp != NULL) {
473 				linkb(*decrmp, ssl->handshake_sendbuf);
474 			} else {
475 				*decrmp = ssl->handshake_sendbuf;
476 			}
477 			ssl->handshake_sendbuf = NULL;
478 
479 			*more = ((ssl->rec_ass_head != NULL) &&
480 			    (!ssl->activeinput));
481 			mutex_exit(&ssl->kssl_lock);
482 			return (kssl_cmd);
483 		}
484 
485 		if (ssl->hs_waitstate == idle_handshake) {
486 			*more = ((ssl->rec_ass_head != NULL) &&
487 			    (!ssl->activeinput));
488 		}
489 
490 		if (outmp != NULL) {
491 			*decrmp = outmp;
492 			/*
493 			 * Don't process any packet after an application_data.
494 			 * We could well receive the close_notify which should
495 			 * be handled separately.
496 			 */
497 			mutex_exit(&ssl->kssl_lock);
498 			return (kssl_cmd);
499 		}
500 		/*
501 		 * The current record isn't done yet. Don't start the next one
502 		 */
503 		if (ssl->activeinput) {
504 			mutex_exit(&ssl->kssl_lock);
505 			return (kssl_cmd);
506 		}
507 	} while ((recmp = kssl_get_next_record(ssl)) != NULL);
508 
509 	mutex_exit(&ssl->kssl_lock);
510 	return (kssl_cmd);
511 
512 sendnewalert:
513 	kssl_send_alert(ssl, alert_fatal, unexpected_message);
514 	if (mp != NULL) {
515 		freeb(mp);
516 	}
517 
518 sendalert:
519 	*decrmp = ssl->alert_sendbuf;
520 	ssl->alert_sendbuf = NULL;
521 	mutex_exit(&ssl->kssl_lock);
522 	return (KSSL_CMD_SEND);
523 }
524 
525 /*
526  * Decrypt and verify the MAC of an incoming chain of application_data record.
527  * Each block has exactly one SSL record.
528  * This routine recycles its incoming mblk, and flags it as DBLK_COOKED
529  */
530 kssl_cmd_t
531 kssl_handle_record(kssl_ctx_t ctx, mblk_t **mpp, mblk_t **outmp)
532 {
533 	uchar_t *recend, *rec_sz_p;
534 	uchar_t *real_recend;
535 	mblk_t *prevmp = NULL, *nextmp, *mp = *mpp, *copybp;
536 	int mac_sz;
537 	uchar_t version[2];
538 	uint16_t rec_sz;
539 	SSL3AlertDescription desc;
540 	SSL3ContentType content_type;
541 	ssl_t *ssl;
542 	KSSLCipherSpec *spec;
543 	int error = 0, ret;
544 	kssl_cmd_t kssl_cmd = KSSL_CMD_DELIVER_PROXY;
545 	boolean_t deliverit = B_FALSE;
546 	crypto_data_t cipher_data;
547 
548 	ASSERT(ctx != NULL);
549 
550 	ssl = (ssl_t *)(ctx);
551 
552 	*outmp = NULL;
553 
554 more:
555 
556 	while (mp != NULL) {
557 
558 		if (DB_REF(mp) > 1) {
559 			/*
560 			 * Fortunately copyb() preserves the offset,
561 			 * tail space and alignement so the copy is
562 			 * ready to be made an SSL record.
563 			 */
564 			if ((copybp = copyb(mp)) == NULL)
565 				return (NULL);
566 
567 			copybp->b_cont = mp->b_cont;
568 			if (mp == *mpp) {
569 				*mpp = copybp;
570 			} else {
571 				prevmp->b_cont = copybp;
572 			}
573 			freeb(mp);
574 			mp = copybp;
575 		}
576 
577 		content_type = (SSL3ContentType)mp->b_rptr[0];
578 
579 		if (content_type != content_application_data) {
580 			nextmp = mp->b_cont;
581 
582 			/* Remove this message */
583 			if (prevmp != NULL) {
584 				prevmp->b_cont = nextmp;
585 
586 				/*
587 				 * If we had processed blocks that need to
588 				 * be delivered, then remember that error code
589 				 */
590 				if (kssl_cmd == KSSL_CMD_DELIVER_PROXY)
591 					deliverit = B_TRUE;
592 			}
593 
594 			mutex_enter(&ssl->kssl_lock);
595 			kssl_cmd = kssl_handle_any_record(ssl, mp, outmp,
596 			    NULL, NULL);
597 
598 			if (ssl->alert_sendbuf != NULL) {
599 				goto sendalert;
600 			}
601 			mutex_exit(&ssl->kssl_lock);
602 
603 			if (deliverit) {
604 				kssl_cmd = KSSL_CMD_DELIVER_PROXY;
605 			}
606 
607 			mp = nextmp;
608 			continue;
609 		}
610 
611 		version[0] = mp->b_rptr[1];
612 		version[1] = mp->b_rptr[2];
613 		rec_sz_p = SSL3_REC_SIZE(mp);
614 		rec_sz = BE16_TO_U16(rec_sz_p);
615 
616 		mp->b_rptr += SSL3_HDR_LEN;
617 		recend = mp->b_rptr + rec_sz;
618 		real_recend = recend;
619 
620 		spec = &ssl->spec[KSSL_READ];
621 		mac_sz = spec->mac_hashsz;
622 		if (spec->cipher_ctx != 0) {
623 			cipher_data.cd_format = CRYPTO_DATA_RAW;
624 			cipher_data.cd_offset = 0;
625 			cipher_data.cd_length = rec_sz;
626 			cipher_data.cd_miscdata = NULL;
627 			cipher_data.cd_raw.iov_base = (char *)mp->b_rptr;
628 			cipher_data.cd_raw.iov_len = rec_sz;
629 			error = crypto_decrypt_update(spec->cipher_ctx,
630 			    &cipher_data, NULL, NULL);
631 			if (CRYPTO_ERR(error)) {
632 #ifdef	DEBUG
633 				cmn_err(CE_WARN, "kssl_handle_record: "
634 				    "crypto_decrypt_update failed: 0x%02X",
635 				    error);
636 #endif	/* DEBUG */
637 				KSSL_COUNTER(record_decrypt_failure, 1);
638 				mp->b_rptr = recend;
639 				desc = decrypt_error;
640 				goto makealert;
641 			}
642 		}
643 		if (spec->cipher_type == type_block) {
644 			uint_t pad_sz = recend[-1];
645 			pad_sz++;
646 			if (pad_sz + mac_sz > rec_sz) {
647 				mp->b_rptr = recend;
648 				desc = bad_record_mac;
649 				goto makealert;
650 			}
651 			rec_sz -= pad_sz;
652 			recend -= pad_sz;
653 		}
654 		if (mac_sz != 0) {
655 			uchar_t hash[MAX_HASH_LEN];
656 			if (rec_sz < mac_sz) {
657 				mp->b_rptr = real_recend;
658 				desc = bad_record_mac;
659 				goto makealert;
660 			}
661 			rec_sz -= mac_sz;
662 			recend -= mac_sz;
663 			ret = kssl_compute_record_mac(ssl, KSSL_READ,
664 				ssl->seq_num[KSSL_READ], content_type,
665 				version, mp->b_rptr, rec_sz, hash);
666 			if (ret != CRYPTO_SUCCESS ||
667 			    bcmp(hash, recend, mac_sz)) {
668 				mp->b_rptr = real_recend;
669 				desc = bad_record_mac;
670 #ifdef	DEBUG
671 				cmn_err(CE_WARN, "kssl_handle_record: "
672 					"msg MAC mismatch");
673 #endif	/* DEBUG */
674 				KSSL_COUNTER(verify_mac_failure, 1);
675 				goto makealert;
676 			}
677 			ssl->seq_num[KSSL_READ]++;
678 		}
679 
680 		if (ssl->hs_waitstate != idle_handshake) {
681 			mp->b_rptr = real_recend;
682 			desc = unexpected_message;
683 			goto makealert;
684 		}
685 		mp->b_wptr = recend;
686 
687 		prevmp = mp;
688 		mp = mp->b_cont;
689 	}
690 
691 	KSSL_COUNTER(appdata_record_ins, 1);
692 	return (kssl_cmd);
693 
694 makealert:
695 	nextmp = mp->b_cont;
696 	freeb(mp);
697 	mp = nextmp;
698 	mutex_enter(&ssl->kssl_lock);
699 	kssl_send_alert(ssl, alert_fatal, desc);
700 
701 	if (ssl->alert_sendbuf == NULL) {
702 		/* internal memory allocation failure. just return. */
703 #ifdef	DEBUG
704 		cmn_err(CE_WARN, "kssl_handle_record: "
705 		    "alert message allocation failed");
706 #endif	/* DEBUG */
707 		mutex_exit(&ssl->kssl_lock);
708 
709 		if (mp) {
710 			prevmp = NULL;
711 			goto more;
712 		}
713 
714 		return (KSSL_CMD_NONE);
715 	}
716 	kssl_cmd = KSSL_CMD_SEND;
717 sendalert:
718 	if (*outmp == NULL) {
719 		*outmp = ssl->alert_sendbuf;
720 	} else {
721 		linkb(*outmp, ssl->alert_sendbuf);
722 	}
723 	ssl->alert_sendbuf = NULL;
724 	mutex_exit(&ssl->kssl_lock);
725 
726 	if (mp) {
727 		prevmp = NULL;
728 		goto more;
729 	}
730 
731 	return (kssl_cmd);
732 }
733 /*
734  * This is the routine that handles incoming SSL records.
735  * When called the first time, with a NULL context, this routine expects
736  * a ClientHello SSL Handshake packet and shall allocate a context
737  * of a new SSL connection.
738  * During the rest of the handshake packets, the routine adjusts the
739  * state of the context according to the record received.
740  * After the ChangeCipherSpec message is received, the routine first
741  * decrypts/authenticated the packet using the key materials in the
742  * connection's context.
743  * The return code tells the caller what to do with the returned packet.
744  */
745 static kssl_cmd_t
746 kssl_handle_any_record(kssl_ctx_t ctx, mblk_t *mp, mblk_t **decrmp,
747     kssl_callback_t cbfn, void *arg)
748 {
749 	uchar_t *recend, *rec_sz_p;
750 	uchar_t version[2];
751 	uchar_t *real_recend, *save_rptr, *save_wptr;
752 	int rhsz = SSL3_HDR_LEN;
753 	uint16_t rec_sz;
754 	int sz;
755 	int mac_sz;
756 	SSL3AlertDescription desc;
757 	SSL3AlertLevel level;
758 	SSL3ContentType content_type;
759 	ssl_t *ssl;
760 	KSSLCipherSpec *spec;
761 	int error = 0, ret;
762 
763 	ASSERT(ctx != NULL);
764 
765 	ssl = (ssl_t *)(ctx);
766 
767 	*decrmp = NULL;
768 
769 	save_rptr = mp->b_rptr;
770 	save_wptr = mp->b_wptr;
771 
772 	ASSERT(MUTEX_HELD(&ssl->kssl_lock));
773 
774 	content_type = (SSL3ContentType)mp->b_rptr[0];
775 	if (content_type == content_handshake_v2) {
776 		if (ssl->hs_waitstate == wait_client_hello) {
777 			/* V2 compatible ClientHello */
778 			if (mp->b_rptr[3] == 0x03 &&
779 			    (mp->b_rptr[4] == 0x01 ||
780 				mp->b_rptr[4] == 0x00)) {
781 				ssl->major_version = version[0] = mp->b_rptr[3];
782 				ssl->minor_version = version[1] = mp->b_rptr[4];
783 			} else {
784 			/* We don't support "pure" SSLv2 */
785 				desc = protocol_version;
786 				goto sendalert;
787 			}
788 		}
789 		rec_sz = (uint16_t)mp->b_rptr[1];
790 		rhsz = 2;
791 	} else {
792 		ssl->major_version = version[0] = mp->b_rptr[1];
793 		ssl->minor_version = version[1] = mp->b_rptr[2];
794 		rec_sz_p = SSL3_REC_SIZE(mp);
795 		rec_sz = BE16_TO_U16(rec_sz_p);
796 	}
797 
798 	mp->b_rptr += rhsz;
799 	recend = mp->b_rptr + rec_sz;
800 	real_recend = recend;
801 
802 	spec = &ssl->spec[KSSL_READ];
803 	mac_sz = spec->mac_hashsz;
804 	if (spec->cipher_ctx != 0) {
805 		spec->cipher_data.cd_length = rec_sz;
806 		spec->cipher_data.cd_raw.iov_base = (char *)mp->b_rptr;
807 		spec->cipher_data.cd_raw.iov_len = rec_sz;
808 		error = crypto_decrypt_update(spec->cipher_ctx,
809 		    &spec->cipher_data, NULL, NULL);
810 		if (CRYPTO_ERR(error)) {
811 #ifdef	DEBUG
812 			cmn_err(CE_WARN,
813 				"kssl_handle_any_record: crypto_decrypt_update "
814 				"failed: 0x%02X", error);
815 #endif	/* DEBUG */
816 			KSSL_COUNTER(record_decrypt_failure, 1);
817 			mp->b_rptr = recend;
818 			desc = decrypt_error;
819 			goto sendalert;
820 		}
821 	}
822 	if (spec->cipher_type == type_block) {
823 		uint_t pad_sz = recend[-1];
824 		pad_sz++;
825 		if (pad_sz + mac_sz > rec_sz) {
826 			mp->b_rptr = recend;
827 			desc = bad_record_mac;
828 			goto sendalert;
829 		}
830 		rec_sz -= pad_sz;
831 		recend -= pad_sz;
832 	}
833 	if (mac_sz != 0) {
834 		uchar_t hash[MAX_HASH_LEN];
835 		if (rec_sz < mac_sz) {
836 			mp->b_rptr = real_recend;
837 			desc = bad_record_mac;
838 			goto sendalert;
839 		}
840 		rec_sz -= mac_sz;
841 		recend -= mac_sz;
842 		ret = kssl_compute_record_mac(ssl, KSSL_READ,
843 			ssl->seq_num[KSSL_READ], content_type,
844 			version, mp->b_rptr, rec_sz, hash);
845 		if (ret != CRYPTO_SUCCESS ||
846 		    bcmp(hash, recend, mac_sz)) {
847 			mp->b_rptr = real_recend;
848 			desc = bad_record_mac;
849 #ifdef	DEBUG
850 			cmn_err(CE_WARN, "kssl_handle_any_record: "
851 				"msg MAC mismatch");
852 #endif	/* DEBUG */
853 			KSSL_COUNTER(verify_mac_failure, 1);
854 			goto sendalert;
855 		}
856 		ssl->seq_num[KSSL_READ]++;
857 	}
858 
859 	switch (content_type) {
860 	case content_handshake:
861 		do {
862 			if (error != 0 ||
863 			    /* ignore client renegotiation for now */
864 			    ssl->hs_waitstate == idle_handshake) {
865 				mp->b_rptr = recend;
866 			}
867 			if (mp->b_rptr == recend) {
868 				mp->b_rptr = real_recend;
869 				if (error != 0) {
870 					goto error;
871 				}
872 				freeb(mp);
873 
874 				if (ssl->hs_waitstate == wait_client_key_done)
875 					return (KSSL_CMD_QUEUED);
876 
877 				return ((ssl->handshake_sendbuf != NULL) ?
878 				    KSSL_CMD_SEND : KSSL_CMD_NONE);
879 			}
880 			if (ssl->msg.state < MSG_BODY) {
881 				if (ssl->msg.state == MSG_INIT) {
882 					ssl->msg.type =
883 					    (SSL3HandshakeType)*mp->b_rptr++;
884 					ssl->msg.state = MSG_INIT_LEN;
885 				}
886 				if (ssl->msg.state == MSG_INIT_LEN) {
887 					int msglenb =
888 					    ssl->msg.msglen_bytes;
889 					int msglen = ssl->msg.msglen;
890 					while (mp->b_rptr < recend &&
891 					    msglenb < 3) {
892 						msglen = (msglen << 8) +
893 						    (uint_t)(*mp->b_rptr++);
894 						msglenb++;
895 					}
896 					ssl->msg.msglen_bytes = msglenb;
897 					ssl->msg.msglen = msglen;
898 					if (msglenb == 3) {
899 						ssl->msg.state = MSG_BODY;
900 					}
901 				}
902 				if (mp->b_rptr == recend) {
903 					mp->b_rptr = real_recend;
904 					freeb(mp);
905 					return (KSSL_CMD_NONE);
906 				}
907 			}
908 			ASSERT(ssl->msg.state == MSG_BODY);
909 
910 			sz = recend - mp->b_rptr;
911 
912 			if (ssl->msg.head == NULL &&
913 			    ssl->msg.msglen <= sz) {
914 				continue;
915 			}
916 			if (ssl->msg.head != NULL) {
917 				sz += msgdsize(ssl->msg.head);
918 				if (ssl->msg.msglen <= sz) {
919 					ssl->msg.tail->b_cont = mp;
920 					mp = ssl->msg.head;
921 					ssl->sslcnt = 100;
922 					ssl->msg.head = NULL;
923 					ssl->msg.tail = NULL;
924 					if (pullupmsg(mp, -1)) {
925 						recend = mp->b_rptr + sz;
926 						ASSERT(recend <= mp->b_wptr);
927 						continue;
928 					}
929 					mp->b_rptr = real_recend;
930 					error = ENOMEM;
931 					KSSL_COUNTER(alloc_fails, 1);
932 					goto error;
933 				}
934 			}
935 
936 			mp->b_wptr = recend;
937 
938 			if (ssl->msg.head == NULL) {
939 				ssl->msg.head = mp;
940 				ssl->msg.tail = mp;
941 				return (KSSL_CMD_NONE);
942 			} else {
943 				ssl->msg.tail->b_cont = mp;
944 				ssl->msg.tail = mp;
945 				return (KSSL_CMD_NONE);
946 			}
947 		} while (kssl_handle_handshake_message(ssl, mp, &error, cbfn,
948 		    arg));
949 		if (error == SSL_MISS) {
950 			mp->b_rptr = save_rptr;
951 			mp->b_wptr = save_wptr;
952 			KSSL_COUNTER(fallback_connections, 1);
953 			return (KSSL_CMD_NOT_SUPPORTED);
954 		}
955 		if (ssl->hs_waitstate == wait_client_key_done) {
956 			return (KSSL_CMD_QUEUED);
957 		} else {
958 			return (KSSL_CMD_NONE);
959 		}
960 	case content_alert:
961 		if (rec_sz != 2) {
962 			mp->b_rptr = real_recend;
963 			desc = illegal_parameter;
964 			goto sendalert;
965 		} else {
966 			level = *mp->b_rptr++;
967 			desc = *mp->b_rptr++;
968 			mp->b_rptr = real_recend;
969 			if (level != alert_warning || desc != close_notify) {
970 				if (ssl->sid.cached == B_TRUE) {
971 					kssl_uncache_sid(&ssl->sid,
972 					    ssl->kssl_entry);
973 					ssl->sid.cached = B_FALSE;
974 				}
975 				ssl->fatal_alert = B_TRUE;
976 				error = EBADMSG;
977 				goto error;
978 			} else {
979 				ssl->close_notify = B_TRUE;
980 				ssl->activeinput = B_FALSE;
981 				freeb(mp);
982 				return (KSSL_CMD_NONE);
983 			}
984 		}
985 	case content_change_cipher_spec:
986 		if (ssl->hs_waitstate != wait_change_cipher) {
987 			desc = unexpected_message;
988 		} else if (rec_sz != 1 || *mp->b_rptr != 1) {
989 			desc = illegal_parameter;
990 		} else {
991 			mp->b_rptr = real_recend;
992 			ssl->hs_waitstate = wait_finished;
993 			ssl->seq_num[KSSL_READ] = 0;
994 			if ((error = kssl_spec_init(ssl, KSSL_READ)) != 0) {
995 #ifdef	DEBUG
996 				cmn_err(CE_WARN,
997 					"kssl_spec_init returned error "
998 					"0x%02X", error);
999 #endif	/* DEBUG */
1000 				goto error;
1001 			}
1002 			ssl->activeinput = B_FALSE;
1003 			freeb(mp);
1004 			return (KSSL_CMD_NONE);
1005 		}
1006 		mp->b_rptr = real_recend;
1007 		goto sendalert;
1008 
1009 	case content_application_data:
1010 		if (ssl->hs_waitstate != idle_handshake) {
1011 			mp->b_rptr = real_recend;
1012 			desc = unexpected_message;
1013 			goto sendalert;
1014 		}
1015 		mp->b_wptr = recend;
1016 		*decrmp = mp;
1017 		ssl->activeinput = B_FALSE;
1018 		return (KSSL_CMD_DELIVER_PROXY);
1019 
1020 	case content_handshake_v2:
1021 		error = kssl_handle_v2client_hello(ssl, mp, rec_sz);
1022 		if (error == SSL_MISS) {
1023 			mp->b_rptr = save_rptr;
1024 			mp->b_wptr = save_wptr;
1025 			KSSL_COUNTER(fallback_connections, 1);
1026 			return (KSSL_CMD_NOT_SUPPORTED);
1027 		} else if (error != 0) {
1028 			goto error;
1029 		}
1030 		freeb(mp);
1031 		return (KSSL_CMD_SEND);
1032 	default:
1033 		mp->b_rptr = real_recend;
1034 		desc = unexpected_message;
1035 		break;
1036 	}
1037 
1038 sendalert:
1039 	kssl_send_alert(ssl, alert_fatal, desc);
1040 	*decrmp = ssl->alert_sendbuf;
1041 	ssl->alert_sendbuf = NULL;
1042 	freeb(mp);
1043 	return ((*decrmp != NULL) ? KSSL_CMD_SEND : KSSL_CMD_NONE);
1044 error:
1045 	freeb(mp);
1046 	return (KSSL_CMD_NONE);
1047 }
1048 
1049 /*
1050  * Initialize the context of an SSL connection, coming to the specified
1051  * address.
1052  * the ssl structure returned is held.
1053  */
1054 kssl_status_t
1055 kssl_init_context(kssl_ent_t kssl_ent, ipaddr_t faddr, int mss,
1056     kssl_ctx_t *kssl_ctxp)
1057 {
1058 	ssl_t *ssl = kmem_cache_alloc(kssl_cache, KM_NOSLEEP);
1059 
1060 	if (ssl == NULL) {
1061 		return (KSSL_STS_ERR);
1062 	}
1063 
1064 	kssl_cache_count++;
1065 
1066 	bzero(ssl, sizeof (ssl_t));
1067 
1068 	ssl->kssl_entry = (kssl_entry_t *)kssl_ent;
1069 	KSSL_ENTRY_REFHOLD(ssl->kssl_entry);
1070 
1071 	ssl->faddr = faddr;
1072 	ssl->tcp_mss = mss;
1073 	ssl->sendalert_level = alert_warning;
1074 	ssl->sendalert_desc = close_notify;
1075 	ssl->sid.cached = B_FALSE;
1076 
1077 	*kssl_ctxp = (kssl_ctx_t)ssl;
1078 	KSSL_SSL_REFHOLD(ssl);
1079 	return (KSSL_STS_OK);
1080 }
1081 
1082 /*
1083  * Builds SSL records out of the chain of mblks, and returns it.
1084  * Taked a copy of the message before encypting it if it has another
1085  * reference.
1086  * In case of failure, NULL is returned, and the message will be
1087  * freed by the caller.
1088  * A NULL mp means a close_notify is requested.
1089  */
1090 mblk_t *
1091 kssl_build_record(kssl_ctx_t ctx, mblk_t *mp)
1092 {
1093 	ssl_t *ssl = (ssl_t *)ctx;
1094 	mblk_t *retmp = mp, *bp = mp, *prevbp = mp, *copybp;
1095 
1096 	ASSERT(ssl != NULL);
1097 	ASSERT(mp != NULL);
1098 
1099 	do {
1100 		if (DB_REF(bp) > 1) {
1101 			/*
1102 			 * Fortunately copyb() preserves the offset,
1103 			 * tail space and alignement so the copy is
1104 			 * ready to be made an SSL record.
1105 			 */
1106 			if ((copybp = copyb(bp)) == NULL)
1107 				return (NULL);
1108 
1109 			copybp->b_cont = bp->b_cont;
1110 			if (bp == mp) {
1111 				retmp = copybp;
1112 			} else {
1113 				prevbp->b_cont = copybp;
1114 			}
1115 			freeb(bp);
1116 			bp = copybp;
1117 		}
1118 
1119 		if (kssl_build_single_record(ssl, bp) != KSSL_STS_OK)
1120 			return (NULL);
1121 
1122 		prevbp = bp;
1123 		bp = bp->b_cont;
1124 	} while (bp != NULL);
1125 
1126 	return (retmp);
1127 }
1128 
1129 /*
1130  * Builds a single SSL record
1131  * In-line encryption of the record.
1132  */
1133 static kssl_status_t
1134 kssl_build_single_record(ssl_t *ssl, mblk_t *mp)
1135 {
1136 	int len;
1137 	int reclen = 0;
1138 	uchar_t *recstart, *versionp;
1139 	KSSLCipherSpec *spec;
1140 	int mac_sz;
1141 	int pad_sz = 0;
1142 
1143 
1144 	spec = &ssl->spec[KSSL_WRITE];
1145 	mac_sz = spec->mac_hashsz;
1146 
1147 
1148 	ASSERT(DB_REF(mp) == 1);
1149 	ASSERT((mp->b_rptr - mp->b_datap->db_base >= SSL3_HDR_LEN) &&
1150 	    (mp->b_datap->db_lim - mp->b_wptr >= mac_sz + spec->cipher_bsize));
1151 
1152 	len = MBLKL(mp);
1153 
1154 	ASSERT(len > 0);
1155 
1156 	mutex_enter(&ssl->kssl_lock);
1157 
1158 	recstart = mp->b_rptr = mp->b_rptr - SSL3_HDR_LEN;
1159 	recstart[0] = content_application_data;
1160 	recstart[1] = ssl->major_version;
1161 	recstart[2] = ssl->minor_version;
1162 	versionp = &recstart[1];
1163 
1164 	reclen = len + mac_sz;
1165 	if (spec->cipher_type == type_block) {
1166 		pad_sz = spec->cipher_bsize -
1167 		    (reclen & (spec->cipher_bsize - 1));
1168 		ASSERT(reclen + pad_sz <=
1169 		    SSL3_MAX_RECORD_LENGTH);
1170 		reclen += pad_sz;
1171 	}
1172 	recstart[3] = (reclen >> 8) & 0xff;
1173 	recstart[4] = reclen & 0xff;
1174 
1175 	if (kssl_mac_encrypt_record(ssl, content_application_data, versionp,
1176 	    recstart, mp) != 0) {
1177 		/* Do we need an internal_error Alert here? */
1178 		mutex_exit(&ssl->kssl_lock);
1179 		return (KSSL_STS_ERR);
1180 	}
1181 
1182 	KSSL_COUNTER(appdata_record_outs, 1);
1183 	mutex_exit(&ssl->kssl_lock);
1184 	return (KSSL_STS_OK);
1185 }
1186