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