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