1 /* 2 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 * 5 * STREAMS Crypto Module 6 * 7 * This module is used to facilitate Kerberos encryption 8 * operations for the telnet daemon and rlogin daemon. 9 * Because the Solaris telnet and rlogin daemons run mostly 10 * in-kernel via 'telmod' and 'rlmod', this module must be 11 * pushed on the STREAM *below* telmod or rlmod. 12 * 13 * Parts of the 3DES key derivation code are covered by the 14 * following copyright. 15 * 16 * Copyright (C) 1998 by the FundsXpress, INC. 17 * 18 * All rights reserved. 19 * 20 * Export of this software from the United States of America may require 21 * a specific license from the United States Government. It is the 22 * responsibility of any person or organization contemplating export to 23 * obtain such a license before exporting. 24 * 25 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 26 * distribute this software and its documentation for any purpose and 27 * without fee is hereby granted, provided that the above copyright 28 * notice appear in all copies and that both that copyright notice and 29 * this permission notice appear in supporting documentation, and that 30 * the name of FundsXpress. not be used in advertising or publicity pertaining 31 * to distribution of the software without specific, written prior 32 * permission. FundsXpress makes no representations about the suitability of 33 * this software for any purpose. It is provided "as is" without express 34 * or implied warranty. 35 * 36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 37 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 38 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 39 */ 40 41 #include <sys/types.h> 42 #include <sys/sysmacros.h> 43 #include <sys/errno.h> 44 #include <sys/debug.h> 45 #include <sys/time.h> 46 #include <sys/stropts.h> 47 #include <sys/stream.h> 48 #include <sys/strsubr.h> 49 #include <sys/strlog.h> 50 #include <sys/cmn_err.h> 51 #include <sys/conf.h> 52 #include <sys/sunddi.h> 53 #include <sys/kmem.h> 54 #include <sys/strsun.h> 55 #include <sys/random.h> 56 #include <sys/types.h> 57 #include <sys/byteorder.h> 58 #include <sys/cryptmod.h> 59 #include <sys/crc32.h> 60 #include <sys/policy.h> 61 62 #include <sys/crypto/api.h> 63 64 /* 65 * Function prototypes. 66 */ 67 static int cryptmodopen(queue_t *, dev_t *, int, int, cred_t *); 68 static void cryptmodrput(queue_t *, mblk_t *); 69 static void cryptmodwput(queue_t *, mblk_t *); 70 static int cryptmodclose(queue_t *, int, cred_t *); 71 static int cryptmodwsrv(queue_t *); 72 static int cryptmodrsrv(queue_t *); 73 74 static mblk_t *do_encrypt(queue_t *q, mblk_t *mp); 75 static mblk_t *do_decrypt(queue_t *q, mblk_t *mp); 76 77 #define CRYPTMOD_ID 5150 78 79 #define CFB_BLKSZ 8 80 81 #define K5CLENGTH 5 82 83 static struct module_info cryptmod_minfo = { 84 CRYPTMOD_ID, /* mi_idnum */ 85 "cryptmod", /* mi_idname */ 86 0, /* mi_minpsz */ 87 INFPSZ, /* mi_maxpsz */ 88 65536, /* mi_hiwat */ 89 1024 /* mi_lowat */ 90 }; 91 92 static struct qinit cryptmod_rinit = { 93 (int (*)())cryptmodrput, /* qi_putp */ 94 cryptmodrsrv, /* qi_svc */ 95 cryptmodopen, /* qi_qopen */ 96 cryptmodclose, /* qi_qclose */ 97 NULL, /* qi_qadmin */ 98 &cryptmod_minfo, /* qi_minfo */ 99 NULL /* qi_mstat */ 100 }; 101 102 static struct qinit cryptmod_winit = { 103 (int (*)())cryptmodwput, /* qi_putp */ 104 cryptmodwsrv, /* qi_srvp */ 105 NULL, /* qi_qopen */ 106 NULL, /* qi_qclose */ 107 NULL, /* qi_qadmin */ 108 &cryptmod_minfo, /* qi_minfo */ 109 NULL /* qi_mstat */ 110 }; 111 112 static struct streamtab cryptmod_info = { 113 &cryptmod_rinit, /* st_rdinit */ 114 &cryptmod_winit, /* st_wrinit */ 115 NULL, /* st_muxrinit */ 116 NULL /* st_muxwinit */ 117 }; 118 119 typedef struct { 120 uint_t hash_len; 121 uint_t confound_len; 122 int (*hashfunc)(); 123 } hash_info_t; 124 125 #define MAX_CKSUM_LEN 20 126 #define CONFOUNDER_LEN 8 127 128 #define SHA1_HASHSIZE 20 129 #define MD5_HASHSIZE 16 130 #define CRC32_HASHSIZE 4 131 #define MSGBUF_SIZE 4096 132 #define CONFOUNDER_BYTES 128 133 134 135 static int crc32_calc(uchar_t *, uchar_t *, uint_t); 136 static int md5_calc(uchar_t *, uchar_t *, uint_t); 137 static int sha1_calc(uchar_t *, uchar_t *, uint_t); 138 139 static hash_info_t null_hash = {0, 0, NULL}; 140 static hash_info_t crc32_hash = {CRC32_HASHSIZE, CONFOUNDER_LEN, crc32_calc}; 141 static hash_info_t md5_hash = {MD5_HASHSIZE, CONFOUNDER_LEN, md5_calc}; 142 static hash_info_t sha1_hash = {SHA1_HASHSIZE, CONFOUNDER_LEN, sha1_calc}; 143 144 static crypto_mech_type_t sha1_hmac_mech = CRYPTO_MECH_INVALID; 145 static crypto_mech_type_t md5_hmac_mech = CRYPTO_MECH_INVALID; 146 static crypto_mech_type_t sha1_hash_mech = CRYPTO_MECH_INVALID; 147 static crypto_mech_type_t md5_hash_mech = CRYPTO_MECH_INVALID; 148 149 static int kef_crypt(struct cipher_data_t *, void *, 150 crypto_data_format_t, size_t, int); 151 static mblk_t * 152 arcfour_hmac_md5_encrypt(queue_t *, struct tmodinfo *, 153 mblk_t *, hash_info_t *); 154 static mblk_t * 155 arcfour_hmac_md5_decrypt(queue_t *, struct tmodinfo *, 156 mblk_t *, hash_info_t *); 157 158 static int 159 do_hmac(crypto_mech_type_t, crypto_key_t *, char *, int, char *, int); 160 161 /* 162 * This is the loadable module wrapper. 163 */ 164 #include <sys/modctl.h> 165 166 static struct fmodsw fsw = { 167 "cryptmod", 168 &cryptmod_info, 169 D_MP | D_MTQPAIR 170 }; 171 172 /* 173 * Module linkage information for the kernel. 174 */ 175 static struct modlstrmod modlstrmod = { 176 &mod_strmodops, 177 "STREAMS encryption module", 178 &fsw 179 }; 180 181 static struct modlinkage modlinkage = { 182 MODREV_1, 183 &modlstrmod, 184 NULL 185 }; 186 187 int 188 _init(void) 189 { 190 return (mod_install(&modlinkage)); 191 } 192 193 int 194 _fini(void) 195 { 196 return (mod_remove(&modlinkage)); 197 } 198 199 int 200 _info(struct modinfo *modinfop) 201 { 202 return (mod_info(&modlinkage, modinfop)); 203 } 204 205 static void 206 cleanup(struct cipher_data_t *cd) 207 { 208 if (cd->key != NULL) { 209 bzero(cd->key, cd->keylen); 210 kmem_free(cd->key, cd->keylen); 211 cd->key = NULL; 212 } 213 214 if (cd->ckey != NULL) { 215 /* 216 * ckey is a crypto_key_t structure which references 217 * "cd->key" for its raw key data. Since that was already 218 * cleared out, we don't need another "bzero" here. 219 */ 220 kmem_free(cd->ckey, sizeof (crypto_key_t)); 221 cd->ckey = NULL; 222 } 223 224 if (cd->block != NULL) { 225 kmem_free(cd->block, cd->blocklen); 226 cd->block = NULL; 227 } 228 229 if (cd->saveblock != NULL) { 230 kmem_free(cd->saveblock, cd->blocklen); 231 cd->saveblock = NULL; 232 } 233 234 if (cd->ivec != NULL) { 235 kmem_free(cd->ivec, cd->ivlen); 236 cd->ivec = NULL; 237 } 238 239 if (cd->d_encr_key.ck_data != NULL) { 240 bzero(cd->d_encr_key.ck_data, cd->keylen); 241 kmem_free(cd->d_encr_key.ck_data, cd->keylen); 242 } 243 244 if (cd->d_hmac_key.ck_data != NULL) { 245 bzero(cd->d_hmac_key.ck_data, cd->keylen); 246 kmem_free(cd->d_hmac_key.ck_data, cd->keylen); 247 } 248 249 if (cd->enc_tmpl != NULL) 250 (void) crypto_destroy_ctx_template(cd->enc_tmpl); 251 252 if (cd->hmac_tmpl != NULL) 253 (void) crypto_destroy_ctx_template(cd->hmac_tmpl); 254 255 if (cd->ctx != NULL) { 256 crypto_cancel_ctx(cd->ctx); 257 cd->ctx = NULL; 258 } 259 } 260 261 /* ARGSUSED */ 262 static int 263 cryptmodopen(queue_t *rq, dev_t *dev, int oflag, int sflag, cred_t *crp) 264 { 265 struct tmodinfo *tmi; 266 ASSERT(rq); 267 268 if (sflag != MODOPEN) 269 return (EINVAL); 270 271 (void) (STRLOG(CRYPTMOD_ID, 0, 5, SL_TRACE|SL_NOTE, 272 "cryptmodopen: opening module(PID %d)", 273 ddi_get_pid())); 274 275 if (rq->q_ptr != NULL) { 276 cmn_err(CE_WARN, "cryptmodopen: already opened"); 277 return (0); 278 } 279 280 /* 281 * Allocate and initialize per-Stream structure. 282 */ 283 tmi = (struct tmodinfo *)kmem_zalloc(sizeof (struct tmodinfo), 284 KM_SLEEP); 285 286 tmi->enc_data.method = CRYPT_METHOD_NONE; 287 tmi->dec_data.method = CRYPT_METHOD_NONE; 288 289 tmi->ready = (CRYPT_READ_READY | CRYPT_WRITE_READY); 290 291 rq->q_ptr = WR(rq)->q_ptr = tmi; 292 293 sha1_hmac_mech = crypto_mech2id(SUN_CKM_SHA1_HMAC); 294 md5_hmac_mech = crypto_mech2id(SUN_CKM_MD5_HMAC); 295 sha1_hash_mech = crypto_mech2id(SUN_CKM_SHA1); 296 md5_hash_mech = crypto_mech2id(SUN_CKM_MD5); 297 298 qprocson(rq); 299 300 return (0); 301 } 302 303 /* ARGSUSED */ 304 static int 305 cryptmodclose(queue_t *rq, int flags __unused, cred_t *credp __unused) 306 { 307 struct tmodinfo *tmi = (struct tmodinfo *)rq->q_ptr; 308 ASSERT(tmi); 309 310 qprocsoff(rq); 311 312 cleanup(&tmi->enc_data); 313 cleanup(&tmi->dec_data); 314 315 kmem_free(tmi, sizeof (struct tmodinfo)); 316 rq->q_ptr = WR(rq)->q_ptr = NULL; 317 318 return (0); 319 } 320 321 /* 322 * plaintext_offset 323 * 324 * Calculate exactly how much space is needed in front 325 * of the "plaintext" in an mbuf so it can be positioned 326 * 1 time instead of potentially moving the data multiple 327 * times. 328 */ 329 static int 330 plaintext_offset(struct cipher_data_t *cd) 331 { 332 int headspace = 0; 333 334 /* 4 byte length prepended to all RCMD msgs */ 335 if (ANY_RCMD_MODE(cd->option_mask)) 336 headspace += RCMD_LEN_SZ; 337 338 /* RCMD V2 mode adds an additional 4 byte plaintext length */ 339 if (cd->option_mask & CRYPTOPT_RCMD_MODE_V2) 340 headspace += RCMD_LEN_SZ; 341 342 /* Need extra space for hash and counfounder */ 343 switch (cd->method) { 344 case CRYPT_METHOD_DES_CBC_NULL: 345 headspace += null_hash.hash_len + null_hash.confound_len; 346 break; 347 case CRYPT_METHOD_DES_CBC_CRC: 348 headspace += crc32_hash.hash_len + crc32_hash.confound_len; 349 break; 350 case CRYPT_METHOD_DES_CBC_MD5: 351 headspace += md5_hash.hash_len + md5_hash.confound_len; 352 break; 353 case CRYPT_METHOD_DES3_CBC_SHA1: 354 headspace += sha1_hash.confound_len; 355 break; 356 case CRYPT_METHOD_ARCFOUR_HMAC_MD5: 357 headspace += md5_hash.hash_len + md5_hash.confound_len; 358 break; 359 case CRYPT_METHOD_AES128: 360 case CRYPT_METHOD_AES256: 361 headspace += DEFAULT_AES_BLOCKLEN; 362 break; 363 case CRYPT_METHOD_DES_CFB: 364 case CRYPT_METHOD_NONE: 365 break; 366 } 367 368 return (headspace); 369 } 370 /* 371 * encrypt_size 372 * 373 * Calculate the resulting size when encrypting 'plainlen' bytes 374 * of data. 375 */ 376 static size_t 377 encrypt_size(struct cipher_data_t *cd, size_t plainlen) 378 { 379 size_t cipherlen; 380 381 switch (cd->method) { 382 case CRYPT_METHOD_DES_CBC_NULL: 383 cipherlen = (size_t)P2ROUNDUP(null_hash.hash_len + 384 plainlen, 8); 385 break; 386 case CRYPT_METHOD_DES_CBC_MD5: 387 cipherlen = (size_t)P2ROUNDUP(md5_hash.hash_len + 388 md5_hash.confound_len + 389 plainlen, 8); 390 break; 391 case CRYPT_METHOD_DES_CBC_CRC: 392 cipherlen = (size_t)P2ROUNDUP(crc32_hash.hash_len + 393 crc32_hash.confound_len + 394 plainlen, 8); 395 break; 396 case CRYPT_METHOD_DES3_CBC_SHA1: 397 cipherlen = (size_t)P2ROUNDUP(sha1_hash.confound_len + 398 plainlen, 8) + 399 sha1_hash.hash_len; 400 break; 401 case CRYPT_METHOD_ARCFOUR_HMAC_MD5: 402 cipherlen = (size_t)P2ROUNDUP(md5_hash.confound_len + 403 plainlen, 1) + md5_hash.hash_len; 404 break; 405 case CRYPT_METHOD_AES128: 406 case CRYPT_METHOD_AES256: 407 /* No roundup for AES-CBC-CTS */ 408 cipherlen = DEFAULT_AES_BLOCKLEN + plainlen + 409 AES_TRUNCATED_HMAC_LEN; 410 break; 411 case CRYPT_METHOD_DES_CFB: 412 case CRYPT_METHOD_NONE: 413 cipherlen = plainlen; 414 break; 415 } 416 417 return (cipherlen); 418 } 419 420 /* 421 * des_cfb_encrypt 422 * 423 * Encrypt the mblk data using DES with cipher feedback. 424 * 425 * Given that V[i] is the initial 64 bit vector, V[n] is the nth 64 bit 426 * vector, D[n] is the nth chunk of 64 bits of data to encrypt 427 * (decrypt), and O[n] is the nth chunk of 64 bits of encrypted 428 * (decrypted) data, then: 429 * 430 * V[0] = DES(V[i], key) 431 * O[n] = D[n] <exclusive or > V[n] 432 * V[n+1] = DES(O[n], key) 433 * 434 * The size of the message being encrypted does not change in this 435 * algorithm, num_bytes in == num_bytes out. 436 */ 437 static mblk_t * 438 des_cfb_encrypt(queue_t *q, struct tmodinfo *tmi, mblk_t *mp) 439 { 440 int savedbytes; 441 char *iptr, *optr, *lastoutput; 442 443 lastoutput = optr = (char *)mp->b_rptr; 444 iptr = (char *)mp->b_rptr; 445 savedbytes = tmi->enc_data.bytes % CFB_BLKSZ; 446 447 while (iptr < (char *)mp->b_wptr) { 448 /* 449 * Do DES-ECB. 450 * The first time this runs, the 'tmi->enc_data.block' will 451 * contain the initialization vector that should have been 452 * passed in with the SETUP ioctl. 453 * 454 * V[n] = DES(V[n-1], key) 455 */ 456 if (!(tmi->enc_data.bytes % CFB_BLKSZ)) { 457 int retval = 0; 458 retval = kef_crypt(&tmi->enc_data, 459 tmi->enc_data.block, 460 CRYPTO_DATA_RAW, 461 tmi->enc_data.blocklen, 462 CRYPT_ENCRYPT); 463 464 if (retval != CRYPTO_SUCCESS) { 465 #ifdef DEBUG 466 cmn_err(CE_WARN, "des_cfb_encrypt: kef_crypt " 467 "failed - error 0x%0x", retval); 468 #endif 469 mp->b_datap->db_type = M_ERROR; 470 mp->b_rptr = mp->b_datap->db_base; 471 *mp->b_rptr = EIO; 472 mp->b_wptr = mp->b_rptr + sizeof (char); 473 freemsg(mp->b_cont); 474 mp->b_cont = NULL; 475 qreply(WR(q), mp); 476 return (NULL); 477 } 478 } 479 480 /* O[n] = I[n] ^ V[n] */ 481 *(optr++) = *(iptr++) ^ 482 tmi->enc_data.block[tmi->enc_data.bytes % CFB_BLKSZ]; 483 484 tmi->enc_data.bytes++; 485 /* 486 * Feedback the encrypted output as the input to next DES call. 487 */ 488 if (!(tmi->enc_data.bytes % CFB_BLKSZ)) { 489 char *dbptr = tmi->enc_data.block; 490 /* 491 * Get the last bits of input from the previous 492 * msg block that we haven't yet used as feedback input. 493 */ 494 if (savedbytes > 0) { 495 bcopy(tmi->enc_data.saveblock, 496 dbptr, (size_t)savedbytes); 497 dbptr += savedbytes; 498 } 499 500 /* 501 * Now copy the correct bytes from the current input 502 * stream and update the 'lastoutput' ptr 503 */ 504 bcopy(lastoutput, dbptr, 505 (size_t)(CFB_BLKSZ - savedbytes)); 506 507 lastoutput += (CFB_BLKSZ - savedbytes); 508 savedbytes = 0; 509 } 510 } 511 /* 512 * If there are bytes of input here that we need in the next 513 * block to build an ivec, save them off here. 514 */ 515 if (lastoutput < optr) { 516 bcopy(lastoutput, 517 tmi->enc_data.saveblock + savedbytes, 518 (uint_t)(optr - lastoutput)); 519 } 520 return (mp); 521 } 522 523 /* 524 * des_cfb_decrypt 525 * 526 * Decrypt the data in the mblk using DES in Cipher Feedback mode 527 * 528 * # bytes in == # bytes out, no padding, confounding, or hashing 529 * is added. 530 * 531 */ 532 static mblk_t * 533 des_cfb_decrypt(queue_t *q, struct tmodinfo *tmi, mblk_t *mp) 534 { 535 uint_t len; 536 uint_t savedbytes; 537 char *iptr; 538 char *lastinput; 539 uint_t cp; 540 541 len = MBLKL(mp); 542 543 /* decrypted output goes into the new data buffer */ 544 lastinput = iptr = (char *)mp->b_rptr; 545 546 savedbytes = tmi->dec_data.bytes % tmi->dec_data.blocklen; 547 548 /* 549 * Save the input CFB_BLKSZ bytes at a time. 550 * We are trying to decrypt in-place, but need to keep 551 * a small sliding window of encrypted text to be 552 * used to construct the feedback buffer. 553 */ 554 cp = ((tmi->dec_data.blocklen - savedbytes) > len ? len : 555 tmi->dec_data.blocklen - savedbytes); 556 557 bcopy(lastinput, tmi->dec_data.saveblock + savedbytes, cp); 558 savedbytes += cp; 559 560 lastinput += cp; 561 562 while (iptr < (char *)mp->b_wptr) { 563 /* 564 * Do DES-ECB. 565 * The first time this runs, the 'tmi->dec_data.block' will 566 * contain the initialization vector that should have been 567 * passed in with the SETUP ioctl. 568 */ 569 if (!(tmi->dec_data.bytes % CFB_BLKSZ)) { 570 int retval; 571 retval = kef_crypt(&tmi->dec_data, 572 tmi->dec_data.block, 573 CRYPTO_DATA_RAW, 574 tmi->dec_data.blocklen, 575 CRYPT_ENCRYPT); 576 577 if (retval != CRYPTO_SUCCESS) { 578 #ifdef DEBUG 579 cmn_err(CE_WARN, "des_cfb_decrypt: kef_crypt " 580 "failed - status 0x%0x", retval); 581 #endif 582 mp->b_datap->db_type = M_ERROR; 583 mp->b_rptr = mp->b_datap->db_base; 584 *mp->b_rptr = EIO; 585 mp->b_wptr = mp->b_rptr + sizeof (char); 586 freemsg(mp->b_cont); 587 mp->b_cont = NULL; 588 qreply(WR(q), mp); 589 return (NULL); 590 } 591 } 592 593 /* 594 * To decrypt, XOR the input with the output from the DES call 595 */ 596 *(iptr++) ^= tmi->dec_data.block[tmi->dec_data.bytes % 597 CFB_BLKSZ]; 598 599 tmi->dec_data.bytes++; 600 601 /* 602 * Feedback the encrypted input for next DES call. 603 */ 604 if (!(tmi->dec_data.bytes % tmi->dec_data.blocklen)) { 605 char *dbptr = tmi->dec_data.block; 606 /* 607 * Get the last bits of input from the previous block 608 * that we haven't yet processed. 609 */ 610 if (savedbytes > 0) { 611 bcopy(tmi->dec_data.saveblock, 612 dbptr, savedbytes); 613 dbptr += savedbytes; 614 } 615 616 savedbytes = 0; 617 618 /* 619 * This block makes sure that our local 620 * buffer of input data is full and can 621 * be accessed from the beginning. 622 */ 623 if (lastinput < (char *)mp->b_wptr) { 624 625 /* How many bytes are left in the mblk? */ 626 cp = (((char *)mp->b_wptr - lastinput) > 627 tmi->dec_data.blocklen ? 628 tmi->dec_data.blocklen : 629 (char *)mp->b_wptr - lastinput); 630 631 /* copy what we need */ 632 bcopy(lastinput, tmi->dec_data.saveblock, 633 cp); 634 635 lastinput += cp; 636 savedbytes = cp; 637 } 638 } 639 } 640 641 return (mp); 642 } 643 644 /* 645 * crc32_calc 646 * 647 * Compute a CRC32 checksum on the input 648 */ 649 static int 650 crc32_calc(uchar_t *buf, uchar_t *input, uint_t len) 651 { 652 uint32_t crc; 653 654 CRC32(crc, input, len, 0, crc32_table); 655 656 buf[0] = (uchar_t)(crc & 0xff); 657 buf[1] = (uchar_t)((crc >> 8) & 0xff); 658 buf[2] = (uchar_t)((crc >> 16) & 0xff); 659 buf[3] = (uchar_t)((crc >> 24) & 0xff); 660 661 return (CRYPTO_SUCCESS); 662 } 663 664 static int 665 kef_digest(crypto_mech_type_t digest_type, 666 uchar_t *input, uint_t inlen, 667 uchar_t *output, uint_t hashlen) 668 { 669 iovec_t v1, v2; 670 crypto_data_t d1, d2; 671 crypto_mechanism_t mech; 672 int rv; 673 674 mech.cm_type = digest_type; 675 mech.cm_param = 0; 676 mech.cm_param_len = 0; 677 678 v1.iov_base = (void *)input; 679 v1.iov_len = inlen; 680 681 d1.cd_format = CRYPTO_DATA_RAW; 682 d1.cd_offset = 0; 683 d1.cd_length = v1.iov_len; 684 d1.cd_raw = v1; 685 686 v2.iov_base = (void *)output; 687 v2.iov_len = hashlen; 688 689 d2.cd_format = CRYPTO_DATA_RAW; 690 d2.cd_offset = 0; 691 d2.cd_length = v2.iov_len; 692 d2.cd_raw = v2; 693 694 rv = crypto_digest(&mech, &d1, &d2, NULL); 695 696 return (rv); 697 } 698 699 /* 700 * sha1_calc 701 * 702 * Get a SHA1 hash on the input data. 703 */ 704 static int 705 sha1_calc(uchar_t *output, uchar_t *input, uint_t inlen) 706 { 707 int rv; 708 709 rv = kef_digest(sha1_hash_mech, input, inlen, output, SHA1_HASHSIZE); 710 711 return (rv); 712 } 713 714 /* 715 * Get an MD5 hash on the input data. 716 * md5_calc 717 * 718 */ 719 static int 720 md5_calc(uchar_t *output, uchar_t *input, uint_t inlen) 721 { 722 int rv; 723 724 rv = kef_digest(md5_hash_mech, input, inlen, output, MD5_HASHSIZE); 725 726 return (rv); 727 } 728 729 /* 730 * nfold 731 * duplicate the functionality of the krb5_nfold function from 732 * the userland kerberos mech. 733 * This is needed to derive keys for use with 3DES/SHA1-HMAC 734 * ciphers. 735 */ 736 static void 737 nfold(int inbits, uchar_t *in, int outbits, uchar_t *out) 738 { 739 int a, b, c, lcm; 740 int byte, i, msbit; 741 742 inbits >>= 3; 743 outbits >>= 3; 744 745 /* first compute lcm(n,k) */ 746 a = outbits; 747 b = inbits; 748 749 while (b != 0) { 750 c = b; 751 b = a%b; 752 a = c; 753 } 754 755 lcm = outbits*inbits/a; 756 757 /* now do the real work */ 758 759 bzero(out, outbits); 760 byte = 0; 761 762 /* 763 * Compute the msbit in k which gets added into this byte 764 * first, start with the msbit in the first, unrotated byte 765 * then, for each byte, shift to the right for each repetition 766 * last, pick out the correct byte within that shifted repetition 767 */ 768 for (i = lcm-1; i >= 0; i--) { 769 msbit = (((inbits<<3)-1) 770 +(((inbits<<3)+13)*(i/inbits)) 771 +((inbits-(i%inbits))<<3)) %(inbits<<3); 772 773 /* pull out the byte value itself */ 774 byte += (((in[((inbits-1)-(msbit>>3))%inbits]<<8)| 775 (in[((inbits)-(msbit>>3))%inbits])) 776 >>((msbit&7)+1))&0xff; 777 778 /* do the addition */ 779 byte += out[i%outbits]; 780 out[i%outbits] = byte&0xff; 781 782 byte >>= 8; 783 } 784 785 /* if there's a carry bit left over, add it back in */ 786 if (byte) { 787 for (i = outbits-1; i >= 0; i--) { 788 /* do the addition */ 789 byte += out[i]; 790 out[i] = byte&0xff; 791 792 /* keep around the carry bit, if any */ 793 byte >>= 8; 794 } 795 } 796 } 797 798 #define smask(step) ((1<<step)-1) 799 #define pstep(x, step) (((x)&smask(step))^(((x)>>step)&smask(step))) 800 #define parity_char(x) pstep(pstep(pstep((x), 4), 2), 1) 801 802 /* 803 * Duplicate the functionality of the "dk_derive_key" function 804 * in the Kerberos mechanism. 805 */ 806 static int 807 derive_key(struct cipher_data_t *cdata, uchar_t *constdata, 808 int constlen, char *dkey, int keybytes, 809 int blocklen) 810 { 811 int rv = 0; 812 int n = 0, i; 813 char *inblock; 814 char *rawkey; 815 char *zeroblock; 816 char *saveblock; 817 818 inblock = kmem_zalloc(blocklen, KM_SLEEP); 819 rawkey = kmem_zalloc(keybytes, KM_SLEEP); 820 zeroblock = kmem_zalloc(blocklen, KM_SLEEP); 821 822 if (constlen == blocklen) 823 bcopy(constdata, inblock, blocklen); 824 else 825 nfold(constlen * 8, constdata, 826 blocklen * 8, (uchar_t *)inblock); 827 828 /* 829 * zeroblock is an IV of all 0's. 830 * 831 * The "block" section of the cdata record is used as the 832 * IV for crypto operations in the kef_crypt function. 833 * 834 * We use 'block' as a generic IV data buffer because it 835 * is attached to the stream state data and thus can 836 * be used to hold information that must carry over 837 * from processing of one mblk to another. 838 * 839 * Here, we save the current IV and replace it with 840 * and empty IV (all 0's) for use when deriving the 841 * keys. Once the key derivation is done, we swap the 842 * old IV back into place. 843 */ 844 saveblock = cdata->block; 845 cdata->block = zeroblock; 846 847 while (n < keybytes) { 848 rv = kef_crypt(cdata, inblock, CRYPTO_DATA_RAW, 849 blocklen, CRYPT_ENCRYPT); 850 if (rv != CRYPTO_SUCCESS) { 851 /* put the original IV block back in place */ 852 cdata->block = saveblock; 853 cmn_err(CE_WARN, "failed to derive a key: %0x", rv); 854 goto cleanup; 855 } 856 857 if (keybytes - n < blocklen) { 858 bcopy(inblock, rawkey+n, (keybytes-n)); 859 break; 860 } 861 bcopy(inblock, rawkey+n, blocklen); 862 n += blocklen; 863 } 864 /* put the original IV block back in place */ 865 cdata->block = saveblock; 866 867 /* finally, make the key */ 868 if (cdata->method == CRYPT_METHOD_DES3_CBC_SHA1) { 869 /* 870 * 3DES key derivation requires that we make sure the 871 * key has the proper parity. 872 */ 873 for (i = 0; i < 3; i++) { 874 bcopy(rawkey+(i*7), dkey+(i*8), 7); 875 876 /* 'dkey' is our derived key output buffer */ 877 dkey[i*8+7] = (((dkey[i*8]&1)<<1) | 878 ((dkey[i*8+1]&1)<<2) | 879 ((dkey[i*8+2]&1)<<3) | 880 ((dkey[i*8+3]&1)<<4) | 881 ((dkey[i*8+4]&1)<<5) | 882 ((dkey[i*8+5]&1)<<6) | 883 ((dkey[i*8+6]&1)<<7)); 884 885 for (n = 0; n < 8; n++) { 886 dkey[i*8 + n] &= 0xfe; 887 dkey[i*8 + n] |= 1^parity_char(dkey[i*8 + n]); 888 } 889 } 890 } else if (IS_AES_METHOD(cdata->method)) { 891 bcopy(rawkey, dkey, keybytes); 892 } 893 cleanup: 894 kmem_free(inblock, blocklen); 895 kmem_free(zeroblock, blocklen); 896 kmem_free(rawkey, keybytes); 897 return (rv); 898 } 899 900 /* 901 * create_derived_keys 902 * 903 * Algorithm for deriving a new key and an HMAC key 904 * before computing the 3DES-SHA1-HMAC operation on the plaintext 905 * This algorithm matches the work done by Kerberos mechanism 906 * in userland. 907 */ 908 static int 909 create_derived_keys(struct cipher_data_t *cdata, uint32_t usage, 910 crypto_key_t *enckey, crypto_key_t *hmackey) 911 { 912 uchar_t constdata[K5CLENGTH]; 913 int keybytes; 914 int rv; 915 916 constdata[0] = (usage>>24)&0xff; 917 constdata[1] = (usage>>16)&0xff; 918 constdata[2] = (usage>>8)&0xff; 919 constdata[3] = usage & 0xff; 920 /* Use "0xAA" for deriving encryption key */ 921 constdata[4] = 0xAA; /* from MIT Kerberos code */ 922 923 enckey->ck_length = cdata->keylen * 8; 924 enckey->ck_format = CRYPTO_KEY_RAW; 925 enckey->ck_data = kmem_zalloc(cdata->keylen, KM_SLEEP); 926 927 switch (cdata->method) { 928 case CRYPT_METHOD_DES_CFB: 929 case CRYPT_METHOD_DES_CBC_NULL: 930 case CRYPT_METHOD_DES_CBC_MD5: 931 case CRYPT_METHOD_DES_CBC_CRC: 932 keybytes = 8; 933 break; 934 case CRYPT_METHOD_DES3_CBC_SHA1: 935 keybytes = CRYPT_DES3_KEYBYTES; 936 break; 937 case CRYPT_METHOD_ARCFOUR_HMAC_MD5: 938 case CRYPT_METHOD_ARCFOUR_HMAC_MD5_EXP: 939 keybytes = CRYPT_ARCFOUR_KEYBYTES; 940 break; 941 case CRYPT_METHOD_AES128: 942 keybytes = CRYPT_AES128_KEYBYTES; 943 break; 944 case CRYPT_METHOD_AES256: 945 keybytes = CRYPT_AES256_KEYBYTES; 946 break; 947 } 948 949 /* derive main crypto key */ 950 rv = derive_key(cdata, constdata, sizeof (constdata), 951 enckey->ck_data, keybytes, cdata->blocklen); 952 953 if (rv == CRYPTO_SUCCESS) { 954 955 /* Use "0x55" for deriving mac key */ 956 constdata[4] = 0x55; 957 958 hmackey->ck_length = cdata->keylen * 8; 959 hmackey->ck_format = CRYPTO_KEY_RAW; 960 hmackey->ck_data = kmem_zalloc(cdata->keylen, KM_SLEEP); 961 962 rv = derive_key(cdata, constdata, sizeof (constdata), 963 hmackey->ck_data, keybytes, 964 cdata->blocklen); 965 } else { 966 cmn_err(CE_WARN, "failed to derive crypto key: %02x", rv); 967 } 968 969 return (rv); 970 } 971 972 /* 973 * Compute 3-DES crypto and HMAC. 974 */ 975 static int 976 kef_decr_hmac(struct cipher_data_t *cdata, 977 mblk_t *mp, int length, 978 char *hmac, int hmaclen) 979 { 980 int rv = CRYPTO_FAILED; 981 982 crypto_mechanism_t encr_mech; 983 crypto_mechanism_t mac_mech; 984 crypto_data_t dd; 985 crypto_data_t mac; 986 iovec_t v1; 987 988 ASSERT(cdata != NULL); 989 ASSERT(mp != NULL); 990 ASSERT(hmac != NULL); 991 992 bzero(&dd, sizeof (dd)); 993 dd.cd_format = CRYPTO_DATA_MBLK; 994 dd.cd_offset = 0; 995 dd.cd_length = length; 996 dd.cd_mp = mp; 997 998 v1.iov_base = hmac; 999 v1.iov_len = hmaclen; 1000 1001 mac.cd_format = CRYPTO_DATA_RAW; 1002 mac.cd_offset = 0; 1003 mac.cd_length = hmaclen; 1004 mac.cd_raw = v1; 1005 1006 /* 1007 * cdata->block holds the IVEC 1008 */ 1009 encr_mech.cm_type = cdata->mech_type; 1010 encr_mech.cm_param = cdata->block; 1011 1012 if (cdata->block != NULL) 1013 encr_mech.cm_param_len = cdata->blocklen; 1014 else 1015 encr_mech.cm_param_len = 0; 1016 1017 rv = crypto_decrypt(&encr_mech, &dd, &cdata->d_encr_key, 1018 cdata->enc_tmpl, NULL, NULL); 1019 if (rv != CRYPTO_SUCCESS) { 1020 cmn_err(CE_WARN, "crypto_decrypt failed: %0x", rv); 1021 return (rv); 1022 } 1023 1024 mac_mech.cm_type = sha1_hmac_mech; 1025 mac_mech.cm_param = NULL; 1026 mac_mech.cm_param_len = 0; 1027 1028 /* 1029 * Compute MAC of the plaintext decrypted above. 1030 */ 1031 rv = crypto_mac(&mac_mech, &dd, &cdata->d_hmac_key, 1032 cdata->hmac_tmpl, &mac, NULL); 1033 1034 if (rv != CRYPTO_SUCCESS) { 1035 cmn_err(CE_WARN, "crypto_mac failed: %0x", rv); 1036 } 1037 1038 return (rv); 1039 } 1040 1041 /* 1042 * Compute 3-DES crypto and HMAC. 1043 */ 1044 static int 1045 kef_encr_hmac(struct cipher_data_t *cdata, 1046 mblk_t *mp, int length, 1047 char *hmac, int hmaclen) 1048 { 1049 int rv = CRYPTO_FAILED; 1050 1051 crypto_mechanism_t encr_mech; 1052 crypto_mechanism_t mac_mech; 1053 crypto_data_t dd; 1054 crypto_data_t mac; 1055 iovec_t v1; 1056 1057 ASSERT(cdata != NULL); 1058 ASSERT(mp != NULL); 1059 ASSERT(hmac != NULL); 1060 1061 bzero(&dd, sizeof (dd)); 1062 dd.cd_format = CRYPTO_DATA_MBLK; 1063 dd.cd_offset = 0; 1064 dd.cd_length = length; 1065 dd.cd_mp = mp; 1066 1067 v1.iov_base = hmac; 1068 v1.iov_len = hmaclen; 1069 1070 mac.cd_format = CRYPTO_DATA_RAW; 1071 mac.cd_offset = 0; 1072 mac.cd_length = hmaclen; 1073 mac.cd_raw = v1; 1074 1075 /* 1076 * cdata->block holds the IVEC 1077 */ 1078 encr_mech.cm_type = cdata->mech_type; 1079 encr_mech.cm_param = cdata->block; 1080 1081 if (cdata->block != NULL) 1082 encr_mech.cm_param_len = cdata->blocklen; 1083 else 1084 encr_mech.cm_param_len = 0; 1085 1086 mac_mech.cm_type = sha1_hmac_mech; 1087 mac_mech.cm_param = NULL; 1088 mac_mech.cm_param_len = 0; 1089 1090 rv = crypto_mac(&mac_mech, &dd, &cdata->d_hmac_key, 1091 cdata->hmac_tmpl, &mac, NULL); 1092 1093 if (rv != CRYPTO_SUCCESS) { 1094 cmn_err(CE_WARN, "crypto_mac failed: %0x", rv); 1095 return (rv); 1096 } 1097 1098 rv = crypto_encrypt(&encr_mech, &dd, &cdata->d_encr_key, 1099 cdata->enc_tmpl, NULL, NULL); 1100 if (rv != CRYPTO_SUCCESS) { 1101 cmn_err(CE_WARN, "crypto_encrypt failed: %0x", rv); 1102 } 1103 1104 return (rv); 1105 } 1106 1107 /* 1108 * kef_crypt 1109 * 1110 * Use the Kernel encryption framework to provide the 1111 * crypto operations for the indicated data. 1112 */ 1113 static int 1114 kef_crypt(struct cipher_data_t *cdata, 1115 void *indata, crypto_data_format_t fmt, 1116 size_t length, int mode) 1117 { 1118 int rv = CRYPTO_FAILED; 1119 1120 crypto_mechanism_t mech; 1121 crypto_key_t crkey; 1122 iovec_t v1; 1123 crypto_data_t d1; 1124 1125 ASSERT(cdata != NULL); 1126 ASSERT(indata != NULL); 1127 ASSERT(fmt == CRYPTO_DATA_RAW || fmt == CRYPTO_DATA_MBLK); 1128 1129 bzero(&crkey, sizeof (crkey)); 1130 bzero(&d1, sizeof (d1)); 1131 1132 crkey.ck_format = CRYPTO_KEY_RAW; 1133 crkey.ck_data = cdata->key; 1134 1135 /* keys are measured in bits, not bytes, so multiply by 8 */ 1136 crkey.ck_length = cdata->keylen * 8; 1137 1138 if (fmt == CRYPTO_DATA_RAW) { 1139 v1.iov_base = (char *)indata; 1140 v1.iov_len = length; 1141 } 1142 1143 d1.cd_format = fmt; 1144 d1.cd_offset = 0; 1145 d1.cd_length = length; 1146 if (fmt == CRYPTO_DATA_RAW) 1147 d1.cd_raw = v1; 1148 else if (fmt == CRYPTO_DATA_MBLK) 1149 d1.cd_mp = (mblk_t *)indata; 1150 1151 mech.cm_type = cdata->mech_type; 1152 mech.cm_param = cdata->block; 1153 /* 1154 * cdata->block holds the IVEC 1155 */ 1156 if (cdata->block != NULL) 1157 mech.cm_param_len = cdata->blocklen; 1158 else 1159 mech.cm_param_len = 0; 1160 1161 /* 1162 * encrypt and decrypt in-place 1163 */ 1164 if (mode == CRYPT_ENCRYPT) 1165 rv = crypto_encrypt(&mech, &d1, &crkey, NULL, NULL, NULL); 1166 else 1167 rv = crypto_decrypt(&mech, &d1, &crkey, NULL, NULL, NULL); 1168 1169 if (rv != CRYPTO_SUCCESS) { 1170 cmn_err(CE_WARN, "%s returned error %08x", 1171 (mode == CRYPT_ENCRYPT ? "crypto_encrypt" : 1172 "crypto_decrypt"), rv); 1173 return (CRYPTO_FAILED); 1174 } 1175 1176 return (rv); 1177 } 1178 1179 static int 1180 do_hmac(crypto_mech_type_t mech, 1181 crypto_key_t *key, 1182 char *data, int datalen, 1183 char *hmac, int hmaclen) 1184 { 1185 int rv = 0; 1186 crypto_mechanism_t mac_mech; 1187 crypto_data_t dd; 1188 crypto_data_t mac; 1189 iovec_t vdata, vmac; 1190 1191 mac_mech.cm_type = mech; 1192 mac_mech.cm_param = NULL; 1193 mac_mech.cm_param_len = 0; 1194 1195 vdata.iov_base = data; 1196 vdata.iov_len = datalen; 1197 1198 bzero(&dd, sizeof (dd)); 1199 dd.cd_format = CRYPTO_DATA_RAW; 1200 dd.cd_offset = 0; 1201 dd.cd_length = datalen; 1202 dd.cd_raw = vdata; 1203 1204 vmac.iov_base = hmac; 1205 vmac.iov_len = hmaclen; 1206 1207 mac.cd_format = CRYPTO_DATA_RAW; 1208 mac.cd_offset = 0; 1209 mac.cd_length = hmaclen; 1210 mac.cd_raw = vmac; 1211 1212 /* 1213 * Compute MAC of the plaintext decrypted above. 1214 */ 1215 rv = crypto_mac(&mac_mech, &dd, key, NULL, &mac, NULL); 1216 1217 if (rv != CRYPTO_SUCCESS) { 1218 cmn_err(CE_WARN, "crypto_mac failed: %0x", rv); 1219 } 1220 1221 return (rv); 1222 } 1223 1224 #define XOR_BLOCK(src, dst) \ 1225 (dst)[0] ^= (src)[0]; \ 1226 (dst)[1] ^= (src)[1]; \ 1227 (dst)[2] ^= (src)[2]; \ 1228 (dst)[3] ^= (src)[3]; \ 1229 (dst)[4] ^= (src)[4]; \ 1230 (dst)[5] ^= (src)[5]; \ 1231 (dst)[6] ^= (src)[6]; \ 1232 (dst)[7] ^= (src)[7]; \ 1233 (dst)[8] ^= (src)[8]; \ 1234 (dst)[9] ^= (src)[9]; \ 1235 (dst)[10] ^= (src)[10]; \ 1236 (dst)[11] ^= (src)[11]; \ 1237 (dst)[12] ^= (src)[12]; \ 1238 (dst)[13] ^= (src)[13]; \ 1239 (dst)[14] ^= (src)[14]; \ 1240 (dst)[15] ^= (src)[15] 1241 1242 #define xorblock(x, y) XOR_BLOCK(y, x) 1243 1244 static int 1245 aes_cbc_cts_encrypt(struct tmodinfo *tmi, uchar_t *plain, size_t length) 1246 { 1247 int result = CRYPTO_SUCCESS; 1248 unsigned char tmp[DEFAULT_AES_BLOCKLEN]; 1249 unsigned char tmp2[DEFAULT_AES_BLOCKLEN]; 1250 unsigned char tmp3[DEFAULT_AES_BLOCKLEN]; 1251 int nblocks = 0, blockno; 1252 crypto_data_t ct, pt; 1253 crypto_mechanism_t mech; 1254 1255 mech.cm_type = tmi->enc_data.mech_type; 1256 if (tmi->enc_data.ivlen > 0 && tmi->enc_data.ivec != NULL) { 1257 bcopy(tmi->enc_data.ivec, tmp, DEFAULT_AES_BLOCKLEN); 1258 } else { 1259 bzero(tmp, sizeof (tmp)); 1260 } 1261 mech.cm_param = NULL; 1262 mech.cm_param_len = 0; 1263 1264 nblocks = (length + DEFAULT_AES_BLOCKLEN - 1) / DEFAULT_AES_BLOCKLEN; 1265 1266 bzero(&ct, sizeof (crypto_data_t)); 1267 bzero(&pt, sizeof (crypto_data_t)); 1268 1269 if (nblocks == 1) { 1270 pt.cd_format = CRYPTO_DATA_RAW; 1271 pt.cd_length = length; 1272 pt.cd_raw.iov_base = (char *)plain; 1273 pt.cd_raw.iov_len = length; 1274 1275 result = crypto_encrypt(&mech, &pt, 1276 &tmi->enc_data.d_encr_key, NULL, NULL, NULL); 1277 1278 if (result != CRYPTO_SUCCESS) { 1279 cmn_err(CE_WARN, "aes_cbc_cts_encrypt: " 1280 "crypto_encrypt failed: %0x", result); 1281 } 1282 } else { 1283 size_t nleft; 1284 1285 ct.cd_format = CRYPTO_DATA_RAW; 1286 ct.cd_offset = 0; 1287 ct.cd_length = DEFAULT_AES_BLOCKLEN; 1288 1289 pt.cd_format = CRYPTO_DATA_RAW; 1290 pt.cd_offset = 0; 1291 pt.cd_length = DEFAULT_AES_BLOCKLEN; 1292 1293 result = crypto_encrypt_init(&mech, 1294 &tmi->enc_data.d_encr_key, 1295 tmi->enc_data.enc_tmpl, 1296 &tmi->enc_data.ctx, NULL); 1297 1298 if (result != CRYPTO_SUCCESS) { 1299 cmn_err(CE_WARN, "aes_cbc_cts_encrypt: " 1300 "crypto_encrypt_init failed: %0x", result); 1301 goto cleanup; 1302 } 1303 1304 for (blockno = 0; blockno < nblocks - 2; blockno++) { 1305 xorblock(tmp, plain + blockno * DEFAULT_AES_BLOCKLEN); 1306 1307 pt.cd_raw.iov_base = (char *)tmp; 1308 pt.cd_raw.iov_len = DEFAULT_AES_BLOCKLEN; 1309 1310 ct.cd_raw.iov_base = (char *)plain + 1311 blockno * DEFAULT_AES_BLOCKLEN; 1312 ct.cd_raw.iov_len = DEFAULT_AES_BLOCKLEN; 1313 1314 result = crypto_encrypt_update(tmi->enc_data.ctx, 1315 &pt, &ct, NULL); 1316 1317 if (result != CRYPTO_SUCCESS) { 1318 cmn_err(CE_WARN, "aes_cbc_cts_encrypt: " 1319 "crypto_encrypt_update failed: %0x", 1320 result); 1321 goto cleanup; 1322 } 1323 /* copy result over original bytes */ 1324 /* make another copy for the next XOR step */ 1325 bcopy(plain + blockno * DEFAULT_AES_BLOCKLEN, 1326 tmp, DEFAULT_AES_BLOCKLEN); 1327 } 1328 /* XOR cipher text from n-3 with plain text from n-2 */ 1329 xorblock(tmp, plain + (nblocks - 2) * DEFAULT_AES_BLOCKLEN); 1330 1331 pt.cd_raw.iov_base = (char *)tmp; 1332 pt.cd_raw.iov_len = DEFAULT_AES_BLOCKLEN; 1333 1334 ct.cd_raw.iov_base = (char *)tmp2; 1335 ct.cd_raw.iov_len = DEFAULT_AES_BLOCKLEN; 1336 1337 /* encrypt XOR-ed block N-2 */ 1338 result = crypto_encrypt_update(tmi->enc_data.ctx, 1339 &pt, &ct, NULL); 1340 if (result != CRYPTO_SUCCESS) { 1341 cmn_err(CE_WARN, "aes_cbc_cts_encrypt: " 1342 "crypto_encrypt_update(2) failed: %0x", 1343 result); 1344 goto cleanup; 1345 } 1346 nleft = length - (nblocks - 1) * DEFAULT_AES_BLOCKLEN; 1347 1348 bzero(tmp3, sizeof (tmp3)); 1349 /* Save final plaintext bytes from n-1 */ 1350 bcopy(plain + (nblocks - 1) * DEFAULT_AES_BLOCKLEN, tmp3, 1351 nleft); 1352 1353 /* Overwrite n-1 with cipher text from n-2 */ 1354 bcopy(tmp2, plain + (nblocks - 1) * DEFAULT_AES_BLOCKLEN, 1355 nleft); 1356 1357 bcopy(tmp2, tmp, DEFAULT_AES_BLOCKLEN); 1358 /* XOR cipher text from n-1 with plain text from n-1 */ 1359 xorblock(tmp, tmp3); 1360 1361 pt.cd_raw.iov_base = (char *)tmp; 1362 pt.cd_raw.iov_len = DEFAULT_AES_BLOCKLEN; 1363 1364 ct.cd_raw.iov_base = (char *)tmp2; 1365 ct.cd_raw.iov_len = DEFAULT_AES_BLOCKLEN; 1366 1367 /* encrypt block N-2 */ 1368 result = crypto_encrypt_update(tmi->enc_data.ctx, 1369 &pt, &ct, NULL); 1370 1371 if (result != CRYPTO_SUCCESS) { 1372 cmn_err(CE_WARN, "aes_cbc_cts_encrypt: " 1373 "crypto_encrypt_update(3) failed: %0x", 1374 result); 1375 goto cleanup; 1376 } 1377 1378 bcopy(tmp2, plain + (nblocks - 2) * DEFAULT_AES_BLOCKLEN, 1379 DEFAULT_AES_BLOCKLEN); 1380 1381 1382 ct.cd_raw.iov_base = (char *)tmp2; 1383 ct.cd_raw.iov_len = DEFAULT_AES_BLOCKLEN; 1384 1385 /* 1386 * Ignore the output on the final step. 1387 */ 1388 result = crypto_encrypt_final(tmi->enc_data.ctx, &ct, NULL); 1389 if (result != CRYPTO_SUCCESS) { 1390 cmn_err(CE_WARN, "aes_cbc_cts_encrypt: " 1391 "crypto_encrypt_final(3) failed: %0x", 1392 result); 1393 } 1394 tmi->enc_data.ctx = NULL; 1395 } 1396 cleanup: 1397 bzero(tmp, sizeof (tmp)); 1398 bzero(tmp2, sizeof (tmp)); 1399 bzero(tmp3, sizeof (tmp)); 1400 bzero(tmi->enc_data.block, tmi->enc_data.blocklen); 1401 return (result); 1402 } 1403 1404 static int 1405 aes_cbc_cts_decrypt(struct tmodinfo *tmi, uchar_t *buff, size_t length) 1406 { 1407 int result = CRYPTO_SUCCESS; 1408 unsigned char tmp[DEFAULT_AES_BLOCKLEN]; 1409 unsigned char tmp2[DEFAULT_AES_BLOCKLEN]; 1410 unsigned char tmp3[DEFAULT_AES_BLOCKLEN]; 1411 int nblocks = 0, blockno; 1412 crypto_data_t ct, pt; 1413 crypto_mechanism_t mech; 1414 1415 mech.cm_type = tmi->enc_data.mech_type; 1416 1417 if (tmi->dec_data.ivec_usage != IVEC_NEVER && 1418 tmi->dec_data.ivlen > 0 && tmi->dec_data.ivec != NULL) { 1419 bcopy(tmi->dec_data.ivec, tmp, DEFAULT_AES_BLOCKLEN); 1420 } else { 1421 bzero(tmp, sizeof (tmp)); 1422 } 1423 mech.cm_param_len = 0; 1424 mech.cm_param = NULL; 1425 1426 nblocks = (length + DEFAULT_AES_BLOCKLEN - 1) / DEFAULT_AES_BLOCKLEN; 1427 1428 bzero(&pt, sizeof (pt)); 1429 bzero(&ct, sizeof (ct)); 1430 1431 if (nblocks == 1) { 1432 ct.cd_format = CRYPTO_DATA_RAW; 1433 ct.cd_length = length; 1434 ct.cd_raw.iov_base = (char *)buff; 1435 ct.cd_raw.iov_len = length; 1436 1437 result = crypto_decrypt(&mech, &ct, 1438 &tmi->dec_data.d_encr_key, NULL, NULL, NULL); 1439 1440 if (result != CRYPTO_SUCCESS) { 1441 cmn_err(CE_WARN, "aes_cbc_cts_decrypt: " 1442 "crypto_decrypt failed: %0x", result); 1443 goto cleanup; 1444 } 1445 } else { 1446 ct.cd_format = CRYPTO_DATA_RAW; 1447 ct.cd_offset = 0; 1448 ct.cd_length = DEFAULT_AES_BLOCKLEN; 1449 1450 pt.cd_format = CRYPTO_DATA_RAW; 1451 pt.cd_offset = 0; 1452 pt.cd_length = DEFAULT_AES_BLOCKLEN; 1453 1454 result = crypto_decrypt_init(&mech, 1455 &tmi->dec_data.d_encr_key, 1456 tmi->dec_data.enc_tmpl, 1457 &tmi->dec_data.ctx, NULL); 1458 1459 if (result != CRYPTO_SUCCESS) { 1460 cmn_err(CE_WARN, "aes_cbc_cts_decrypt: " 1461 "crypto_decrypt_init failed: %0x", result); 1462 goto cleanup; 1463 } 1464 for (blockno = 0; blockno < nblocks - 2; blockno++) { 1465 ct.cd_raw.iov_base = (char *)buff + 1466 (blockno * DEFAULT_AES_BLOCKLEN); 1467 ct.cd_raw.iov_len = DEFAULT_AES_BLOCKLEN; 1468 1469 pt.cd_raw.iov_base = (char *)tmp2; 1470 pt.cd_raw.iov_len = DEFAULT_AES_BLOCKLEN; 1471 1472 /* 1473 * Save the input to the decrypt so it can 1474 * be used later for an XOR operation 1475 */ 1476 bcopy(buff + (blockno * DEFAULT_AES_BLOCKLEN), 1477 tmi->dec_data.block, DEFAULT_AES_BLOCKLEN); 1478 1479 result = crypto_decrypt_update(tmi->dec_data.ctx, 1480 &ct, &pt, NULL); 1481 if (result != CRYPTO_SUCCESS) { 1482 cmn_err(CE_WARN, "aes_cbc_cts_decrypt: " 1483 "crypto_decrypt_update(1) error - " 1484 "result = 0x%08x", result); 1485 goto cleanup; 1486 } 1487 xorblock(tmp2, tmp); 1488 bcopy(tmp2, buff + blockno * DEFAULT_AES_BLOCKLEN, 1489 DEFAULT_AES_BLOCKLEN); 1490 /* 1491 * The original cipher text is used as the xor 1492 * for the next block, save it here. 1493 */ 1494 bcopy(tmi->dec_data.block, tmp, DEFAULT_AES_BLOCKLEN); 1495 } 1496 ct.cd_raw.iov_base = (char *)buff + 1497 ((nblocks - 2) * DEFAULT_AES_BLOCKLEN); 1498 ct.cd_raw.iov_len = DEFAULT_AES_BLOCKLEN; 1499 pt.cd_raw.iov_base = (char *)tmp2; 1500 pt.cd_raw.iov_len = DEFAULT_AES_BLOCKLEN; 1501 1502 result = crypto_decrypt_update(tmi->dec_data.ctx, 1503 &ct, &pt, NULL); 1504 if (result != CRYPTO_SUCCESS) { 1505 cmn_err(CE_WARN, 1506 "aes_cbc_cts_decrypt: " 1507 "crypto_decrypt_update(2) error -" 1508 " result = 0x%08x", result); 1509 goto cleanup; 1510 } 1511 bzero(tmp3, sizeof (tmp3)); 1512 bcopy(buff + (nblocks - 1) * DEFAULT_AES_BLOCKLEN, tmp3, 1513 length - ((nblocks - 1) * DEFAULT_AES_BLOCKLEN)); 1514 1515 xorblock(tmp2, tmp3); 1516 bcopy(tmp2, buff + (nblocks - 1) * DEFAULT_AES_BLOCKLEN, 1517 length - ((nblocks - 1) * DEFAULT_AES_BLOCKLEN)); 1518 1519 /* 2nd to last block ... */ 1520 bcopy(tmp3, tmp2, 1521 length - ((nblocks - 1) * DEFAULT_AES_BLOCKLEN)); 1522 1523 ct.cd_raw.iov_base = (char *)tmp2; 1524 ct.cd_raw.iov_len = DEFAULT_AES_BLOCKLEN; 1525 pt.cd_raw.iov_base = (char *)tmp3; 1526 pt.cd_raw.iov_len = DEFAULT_AES_BLOCKLEN; 1527 1528 result = crypto_decrypt_update(tmi->dec_data.ctx, 1529 &ct, &pt, NULL); 1530 if (result != CRYPTO_SUCCESS) { 1531 cmn_err(CE_WARN, 1532 "aes_cbc_cts_decrypt: " 1533 "crypto_decrypt_update(3) error - " 1534 "result = 0x%08x", result); 1535 goto cleanup; 1536 } 1537 xorblock(tmp3, tmp); 1538 1539 1540 /* Finally, update the 2nd to last block and we are done. */ 1541 bcopy(tmp3, buff + (nblocks - 2) * DEFAULT_AES_BLOCKLEN, 1542 DEFAULT_AES_BLOCKLEN); 1543 1544 /* Do Final step, but ignore output */ 1545 pt.cd_raw.iov_base = (char *)tmp2; 1546 pt.cd_raw.iov_len = DEFAULT_AES_BLOCKLEN; 1547 result = crypto_decrypt_final(tmi->dec_data.ctx, &pt, NULL); 1548 if (result != CRYPTO_SUCCESS) { 1549 cmn_err(CE_WARN, "aes_cbc_cts_decrypt: " 1550 "crypto_decrypt_final error - " 1551 "result = 0x%0x", result); 1552 } 1553 tmi->dec_data.ctx = NULL; 1554 } 1555 1556 cleanup: 1557 bzero(tmp, sizeof (tmp)); 1558 bzero(tmp2, sizeof (tmp)); 1559 bzero(tmp3, sizeof (tmp)); 1560 bzero(tmi->dec_data.block, tmi->dec_data.blocklen); 1561 return (result); 1562 } 1563 1564 /* 1565 * AES decrypt 1566 * 1567 * format of ciphertext when using AES 1568 * +-------------+------------+------------+ 1569 * | confounder | msg-data | hmac | 1570 * +-------------+------------+------------+ 1571 */ 1572 static mblk_t * 1573 aes_decrypt(queue_t *q, struct tmodinfo *tmi, mblk_t *mp, 1574 hash_info_t *hash) 1575 { 1576 int result; 1577 size_t enclen; 1578 size_t inlen; 1579 uchar_t hmacbuff[64]; 1580 uchar_t tmpiv[DEFAULT_AES_BLOCKLEN]; 1581 1582 inlen = (size_t)MBLKL(mp); 1583 1584 enclen = inlen - AES_TRUNCATED_HMAC_LEN; 1585 if (tmi->dec_data.ivec_usage != IVEC_NEVER && 1586 tmi->dec_data.ivec != NULL && tmi->dec_data.ivlen > 0) { 1587 int nblocks = (enclen + DEFAULT_AES_BLOCKLEN - 1) / 1588 DEFAULT_AES_BLOCKLEN; 1589 bcopy(mp->b_rptr + DEFAULT_AES_BLOCKLEN * (nblocks - 2), 1590 tmpiv, DEFAULT_AES_BLOCKLEN); 1591 } 1592 1593 /* AES Decrypt */ 1594 result = aes_cbc_cts_decrypt(tmi, mp->b_rptr, enclen); 1595 1596 if (result != CRYPTO_SUCCESS) { 1597 cmn_err(CE_WARN, 1598 "aes_decrypt: aes_cbc_cts_decrypt " 1599 "failed - error %0x", result); 1600 goto cleanup; 1601 } 1602 1603 /* Verify the HMAC */ 1604 result = do_hmac(sha1_hmac_mech, 1605 &tmi->dec_data.d_hmac_key, 1606 (char *)mp->b_rptr, enclen, 1607 (char *)hmacbuff, hash->hash_len); 1608 1609 if (result != CRYPTO_SUCCESS) { 1610 cmn_err(CE_WARN, 1611 "aes_decrypt: do_hmac failed - error %0x", result); 1612 goto cleanup; 1613 } 1614 1615 if (bcmp(hmacbuff, mp->b_rptr + enclen, 1616 AES_TRUNCATED_HMAC_LEN) != 0) { 1617 result = -1; 1618 cmn_err(CE_WARN, "aes_decrypt: checksum verification failed"); 1619 goto cleanup; 1620 } 1621 1622 /* truncate the mblk at the end of the decrypted text */ 1623 mp->b_wptr = mp->b_rptr + enclen; 1624 1625 /* Adjust the beginning of the buffer to skip the confounder */ 1626 mp->b_rptr += DEFAULT_AES_BLOCKLEN; 1627 1628 if (tmi->dec_data.ivec_usage != IVEC_NEVER && 1629 tmi->dec_data.ivec != NULL && tmi->dec_data.ivlen > 0) 1630 bcopy(tmpiv, tmi->dec_data.ivec, DEFAULT_AES_BLOCKLEN); 1631 1632 cleanup: 1633 if (result != CRYPTO_SUCCESS) { 1634 mp->b_datap->db_type = M_ERROR; 1635 mp->b_rptr = mp->b_datap->db_base; 1636 *mp->b_rptr = EIO; 1637 mp->b_wptr = mp->b_rptr + sizeof (char); 1638 freemsg(mp->b_cont); 1639 mp->b_cont = NULL; 1640 qreply(WR(q), mp); 1641 return (NULL); 1642 } 1643 return (mp); 1644 } 1645 1646 /* 1647 * AES encrypt 1648 * 1649 * format of ciphertext when using AES 1650 * +-------------+------------+------------+ 1651 * | confounder | msg-data | hmac | 1652 * +-------------+------------+------------+ 1653 */ 1654 static mblk_t * 1655 aes_encrypt(queue_t *q, struct tmodinfo *tmi, mblk_t *mp, 1656 hash_info_t *hash) 1657 { 1658 int result; 1659 size_t cipherlen; 1660 size_t inlen; 1661 uchar_t hmacbuff[64]; 1662 1663 inlen = (size_t)MBLKL(mp); 1664 1665 cipherlen = encrypt_size(&tmi->enc_data, inlen); 1666 1667 ASSERT(MBLKSIZE(mp) >= cipherlen); 1668 1669 /* 1670 * Shift the rptr back enough to insert the confounder. 1671 */ 1672 mp->b_rptr -= DEFAULT_AES_BLOCKLEN; 1673 1674 /* Get random data for confounder */ 1675 (void) random_get_pseudo_bytes((uint8_t *)mp->b_rptr, 1676 DEFAULT_AES_BLOCKLEN); 1677 1678 /* 1679 * Because we encrypt in-place, we need to calculate 1680 * the HMAC of the plaintext now, then stick it on 1681 * the end of the ciphertext down below. 1682 */ 1683 result = do_hmac(sha1_hmac_mech, 1684 &tmi->enc_data.d_hmac_key, 1685 (char *)mp->b_rptr, DEFAULT_AES_BLOCKLEN + inlen, 1686 (char *)hmacbuff, hash->hash_len); 1687 1688 if (result != CRYPTO_SUCCESS) { 1689 cmn_err(CE_WARN, "aes_encrypt: do_hmac failed - error %0x", 1690 result); 1691 goto cleanup; 1692 } 1693 /* Encrypt using AES-CBC-CTS */ 1694 result = aes_cbc_cts_encrypt(tmi, mp->b_rptr, 1695 inlen + DEFAULT_AES_BLOCKLEN); 1696 1697 if (result != CRYPTO_SUCCESS) { 1698 cmn_err(CE_WARN, "aes_encrypt: aes_cbc_cts_encrypt " 1699 "failed - error %0x", result); 1700 goto cleanup; 1701 } 1702 1703 /* copy the truncated HMAC to the end of the mblk */ 1704 bcopy(hmacbuff, mp->b_rptr + DEFAULT_AES_BLOCKLEN + inlen, 1705 AES_TRUNCATED_HMAC_LEN); 1706 1707 mp->b_wptr = mp->b_rptr + cipherlen; 1708 1709 /* 1710 * The final block of cipher text (not the HMAC) is used 1711 * as the next IV. 1712 */ 1713 if (tmi->enc_data.ivec_usage != IVEC_NEVER && 1714 tmi->enc_data.ivec != NULL) { 1715 int nblocks = (inlen + 2 * DEFAULT_AES_BLOCKLEN - 1) / 1716 DEFAULT_AES_BLOCKLEN; 1717 1718 bcopy(mp->b_rptr + (nblocks - 2) * DEFAULT_AES_BLOCKLEN, 1719 tmi->enc_data.ivec, DEFAULT_AES_BLOCKLEN); 1720 } 1721 1722 cleanup: 1723 if (result != CRYPTO_SUCCESS) { 1724 mp->b_datap->db_type = M_ERROR; 1725 mp->b_rptr = mp->b_datap->db_base; 1726 *mp->b_rptr = EIO; 1727 mp->b_wptr = mp->b_rptr + sizeof (char); 1728 freemsg(mp->b_cont); 1729 mp->b_cont = NULL; 1730 qreply(WR(q), mp); 1731 return (NULL); 1732 } 1733 return (mp); 1734 } 1735 1736 /* 1737 * ARCFOUR-HMAC-MD5 decrypt 1738 * 1739 * format of ciphertext when using ARCFOUR-HMAC-MD5 1740 * +-----------+------------+------------+ 1741 * | hmac | confounder | msg-data | 1742 * +-----------+------------+------------+ 1743 * 1744 */ 1745 static mblk_t * 1746 arcfour_hmac_md5_decrypt(queue_t *q, struct tmodinfo *tmi, mblk_t *mp, 1747 hash_info_t *hash) 1748 { 1749 int result; 1750 size_t cipherlen; 1751 size_t inlen; 1752 size_t saltlen; 1753 crypto_key_t k1, k2; 1754 crypto_data_t indata; 1755 iovec_t v1; 1756 uchar_t ms_exp[9] = {0xab, 0xab, 0xab, 0xab, 0xab, 1757 0xab, 0xab, 0xab, 0xab }; 1758 uchar_t k1data[CRYPT_ARCFOUR_KEYBYTES]; 1759 uchar_t k2data[CRYPT_ARCFOUR_KEYBYTES]; 1760 uchar_t cksum[MD5_HASHSIZE]; 1761 uchar_t saltdata[CRYPT_ARCFOUR_KEYBYTES]; 1762 crypto_mechanism_t mech; 1763 int usage; 1764 1765 bzero(&indata, sizeof (indata)); 1766 1767 /* The usage constant is 1026 for all "old" rcmd mode operations */ 1768 if (tmi->dec_data.option_mask & CRYPTOPT_RCMD_MODE_V1) 1769 usage = RCMDV1_USAGE; 1770 else 1771 usage = ARCFOUR_DECRYPT_USAGE; 1772 1773 /* 1774 * The size at this point should be the size of 1775 * all the plaintext plus the optional plaintext length 1776 * needed for RCMD V2 mode. There should also be room 1777 * at the head of the mblk for the confounder and hash info. 1778 */ 1779 inlen = (size_t)MBLKL(mp); 1780 1781 /* 1782 * The cipherlen does not include the HMAC at the 1783 * head of the buffer. 1784 */ 1785 cipherlen = inlen - hash->hash_len; 1786 1787 ASSERT(MBLKSIZE(mp) >= cipherlen); 1788 if (tmi->dec_data.method == CRYPT_METHOD_ARCFOUR_HMAC_MD5_EXP) { 1789 bcopy(ARCFOUR_EXP_SALT, saltdata, strlen(ARCFOUR_EXP_SALT)); 1790 saltdata[9] = 0; 1791 saltdata[10] = usage & 0xff; 1792 saltdata[11] = (usage >> 8) & 0xff; 1793 saltdata[12] = (usage >> 16) & 0xff; 1794 saltdata[13] = (usage >> 24) & 0xff; 1795 saltlen = 14; 1796 } else { 1797 saltdata[0] = usage & 0xff; 1798 saltdata[1] = (usage >> 8) & 0xff; 1799 saltdata[2] = (usage >> 16) & 0xff; 1800 saltdata[3] = (usage >> 24) & 0xff; 1801 saltlen = 4; 1802 } 1803 /* 1804 * Use the salt value to create a key to be used 1805 * for subsequent HMAC operations. 1806 */ 1807 result = do_hmac(md5_hmac_mech, 1808 tmi->dec_data.ckey, 1809 (char *)saltdata, saltlen, 1810 (char *)k1data, sizeof (k1data)); 1811 if (result != CRYPTO_SUCCESS) { 1812 cmn_err(CE_WARN, 1813 "arcfour_hmac_md5_decrypt: do_hmac(k1)" 1814 "failed - error %0x", result); 1815 goto cleanup; 1816 } 1817 bcopy(k1data, k2data, sizeof (k1data)); 1818 1819 /* 1820 * For the neutered MS RC4 encryption type, 1821 * set the trailing 9 bytes to 0xab per the 1822 * RC4-HMAC spec. 1823 */ 1824 if (tmi->dec_data.method == CRYPT_METHOD_ARCFOUR_HMAC_MD5_EXP) { 1825 bcopy((void *)&k1data[7], ms_exp, sizeof (ms_exp)); 1826 } 1827 1828 mech.cm_type = tmi->dec_data.mech_type; 1829 mech.cm_param = NULL; 1830 mech.cm_param_len = 0; 1831 1832 /* 1833 * If we have not yet initialized the decryption key, 1834 * context, and template, do it now. 1835 */ 1836 if (tmi->dec_data.ctx == NULL || 1837 (tmi->dec_data.option_mask & CRYPTOPT_RCMD_MODE_V1)) { 1838 k1.ck_format = CRYPTO_KEY_RAW; 1839 k1.ck_length = CRYPT_ARCFOUR_KEYBYTES * 8; 1840 k1.ck_data = k1data; 1841 1842 tmi->dec_data.d_encr_key.ck_format = CRYPTO_KEY_RAW; 1843 tmi->dec_data.d_encr_key.ck_length = k1.ck_length; 1844 if (tmi->dec_data.d_encr_key.ck_data == NULL) 1845 tmi->dec_data.d_encr_key.ck_data = kmem_zalloc( 1846 CRYPT_ARCFOUR_KEYBYTES, KM_SLEEP); 1847 1848 /* 1849 * HMAC operation creates the encryption 1850 * key to be used for the decrypt operations. 1851 */ 1852 result = do_hmac(md5_hmac_mech, &k1, 1853 (char *)mp->b_rptr, hash->hash_len, 1854 (char *)tmi->dec_data.d_encr_key.ck_data, 1855 CRYPT_ARCFOUR_KEYBYTES); 1856 1857 1858 if (result != CRYPTO_SUCCESS) { 1859 cmn_err(CE_WARN, 1860 "arcfour_hmac_md5_decrypt: do_hmac(k3)" 1861 "failed - error %0x", result); 1862 goto cleanup; 1863 } 1864 } 1865 1866 tmi->dec_data.enc_tmpl = NULL; 1867 1868 if (tmi->dec_data.ctx == NULL && 1869 (tmi->dec_data.option_mask & CRYPTOPT_RCMD_MODE_V2)) { 1870 /* 1871 * Only create a template if we are doing 1872 * chaining from block to block. 1873 */ 1874 result = crypto_create_ctx_template(&mech, 1875 &tmi->dec_data.d_encr_key, 1876 &tmi->dec_data.enc_tmpl, 1877 KM_SLEEP); 1878 if (result == CRYPTO_NOT_SUPPORTED) { 1879 tmi->dec_data.enc_tmpl = NULL; 1880 } else if (result != CRYPTO_SUCCESS) { 1881 cmn_err(CE_WARN, 1882 "arcfour_hmac_md5_decrypt: " 1883 "failed to create dec template " 1884 "for RC4 encrypt: %0x", result); 1885 goto cleanup; 1886 } 1887 1888 result = crypto_decrypt_init(&mech, 1889 &tmi->dec_data.d_encr_key, 1890 tmi->dec_data.enc_tmpl, 1891 &tmi->dec_data.ctx, NULL); 1892 1893 if (result != CRYPTO_SUCCESS) { 1894 cmn_err(CE_WARN, "crypto_decrypt_init failed:" 1895 " %0x", result); 1896 goto cleanup; 1897 } 1898 } 1899 1900 /* adjust the rptr so we don't decrypt the original hmac field */ 1901 1902 v1.iov_base = (char *)mp->b_rptr + hash->hash_len; 1903 v1.iov_len = cipherlen; 1904 1905 indata.cd_format = CRYPTO_DATA_RAW; 1906 indata.cd_offset = 0; 1907 indata.cd_length = cipherlen; 1908 indata.cd_raw = v1; 1909 1910 if (tmi->dec_data.option_mask & CRYPTOPT_RCMD_MODE_V2) 1911 result = crypto_decrypt_update(tmi->dec_data.ctx, 1912 &indata, NULL, NULL); 1913 else 1914 result = crypto_decrypt(&mech, &indata, 1915 &tmi->dec_data.d_encr_key, NULL, NULL, NULL); 1916 1917 if (result != CRYPTO_SUCCESS) { 1918 cmn_err(CE_WARN, "crypto_decrypt_update failed:" 1919 " %0x", result); 1920 goto cleanup; 1921 } 1922 1923 k2.ck_format = CRYPTO_KEY_RAW; 1924 k2.ck_length = sizeof (k2data) * 8; 1925 k2.ck_data = k2data; 1926 1927 result = do_hmac(md5_hmac_mech, 1928 &k2, 1929 (char *)mp->b_rptr + hash->hash_len, cipherlen, 1930 (char *)cksum, hash->hash_len); 1931 1932 if (result != CRYPTO_SUCCESS) { 1933 cmn_err(CE_WARN, 1934 "arcfour_hmac_md5_decrypt: do_hmac(k2)" 1935 "failed - error %0x", result); 1936 goto cleanup; 1937 } 1938 1939 if (bcmp(cksum, mp->b_rptr, hash->hash_len) != 0) { 1940 cmn_err(CE_WARN, "arcfour_decrypt HMAC comparison failed"); 1941 result = -1; 1942 goto cleanup; 1943 } 1944 1945 /* 1946 * adjust the start of the mblk to skip over the 1947 * hash and confounder. 1948 */ 1949 mp->b_rptr += hash->hash_len + hash->confound_len; 1950 1951 cleanup: 1952 bzero(k1data, sizeof (k1data)); 1953 bzero(k2data, sizeof (k2data)); 1954 bzero(cksum, sizeof (cksum)); 1955 bzero(saltdata, sizeof (saltdata)); 1956 if (result != CRYPTO_SUCCESS) { 1957 mp->b_datap->db_type = M_ERROR; 1958 mp->b_rptr = mp->b_datap->db_base; 1959 *mp->b_rptr = EIO; 1960 mp->b_wptr = mp->b_rptr + sizeof (char); 1961 freemsg(mp->b_cont); 1962 mp->b_cont = NULL; 1963 qreply(WR(q), mp); 1964 return (NULL); 1965 } 1966 return (mp); 1967 } 1968 1969 /* 1970 * ARCFOUR-HMAC-MD5 encrypt 1971 * 1972 * format of ciphertext when using ARCFOUR-HMAC-MD5 1973 * +-----------+------------+------------+ 1974 * | hmac | confounder | msg-data | 1975 * +-----------+------------+------------+ 1976 * 1977 */ 1978 static mblk_t * 1979 arcfour_hmac_md5_encrypt(queue_t *q, struct tmodinfo *tmi, mblk_t *mp, 1980 hash_info_t *hash) 1981 { 1982 int result; 1983 size_t cipherlen; 1984 size_t inlen; 1985 size_t saltlen; 1986 crypto_key_t k1, k2; 1987 crypto_data_t indata; 1988 iovec_t v1; 1989 uchar_t ms_exp[9] = {0xab, 0xab, 0xab, 0xab, 0xab, 1990 0xab, 0xab, 0xab, 0xab }; 1991 uchar_t k1data[CRYPT_ARCFOUR_KEYBYTES]; 1992 uchar_t k2data[CRYPT_ARCFOUR_KEYBYTES]; 1993 uchar_t saltdata[CRYPT_ARCFOUR_KEYBYTES]; 1994 crypto_mechanism_t mech; 1995 int usage; 1996 1997 bzero(&indata, sizeof (indata)); 1998 1999 /* The usage constant is 1026 for all "old" rcmd mode operations */ 2000 if (tmi->enc_data.option_mask & CRYPTOPT_RCMD_MODE_V1) 2001 usage = RCMDV1_USAGE; 2002 else 2003 usage = ARCFOUR_ENCRYPT_USAGE; 2004 2005 mech.cm_type = tmi->enc_data.mech_type; 2006 mech.cm_param = NULL; 2007 mech.cm_param_len = 0; 2008 2009 /* 2010 * The size at this point should be the size of 2011 * all the plaintext plus the optional plaintext length 2012 * needed for RCMD V2 mode. There should also be room 2013 * at the head of the mblk for the confounder and hash info. 2014 */ 2015 inlen = (size_t)MBLKL(mp); 2016 2017 cipherlen = encrypt_size(&tmi->enc_data, inlen); 2018 2019 ASSERT(MBLKSIZE(mp) >= cipherlen); 2020 2021 /* 2022 * Shift the rptr back enough to insert 2023 * the confounder and hash. 2024 */ 2025 mp->b_rptr -= (hash->confound_len + hash->hash_len); 2026 2027 /* zero out the hash area */ 2028 bzero(mp->b_rptr, (size_t)hash->hash_len); 2029 2030 if (cipherlen > inlen) { 2031 bzero(mp->b_wptr, MBLKTAIL(mp)); 2032 } 2033 2034 if (tmi->enc_data.method == CRYPT_METHOD_ARCFOUR_HMAC_MD5_EXP) { 2035 bcopy(ARCFOUR_EXP_SALT, saltdata, strlen(ARCFOUR_EXP_SALT)); 2036 saltdata[9] = 0; 2037 saltdata[10] = usage & 0xff; 2038 saltdata[11] = (usage >> 8) & 0xff; 2039 saltdata[12] = (usage >> 16) & 0xff; 2040 saltdata[13] = (usage >> 24) & 0xff; 2041 saltlen = 14; 2042 } else { 2043 saltdata[0] = usage & 0xff; 2044 saltdata[1] = (usage >> 8) & 0xff; 2045 saltdata[2] = (usage >> 16) & 0xff; 2046 saltdata[3] = (usage >> 24) & 0xff; 2047 saltlen = 4; 2048 } 2049 /* 2050 * Use the salt value to create a key to be used 2051 * for subsequent HMAC operations. 2052 */ 2053 result = do_hmac(md5_hmac_mech, 2054 tmi->enc_data.ckey, 2055 (char *)saltdata, saltlen, 2056 (char *)k1data, sizeof (k1data)); 2057 if (result != CRYPTO_SUCCESS) { 2058 cmn_err(CE_WARN, 2059 "arcfour_hmac_md5_encrypt: do_hmac(k1)" 2060 "failed - error %0x", result); 2061 goto cleanup; 2062 } 2063 2064 bcopy(k1data, k2data, sizeof (k2data)); 2065 2066 /* 2067 * For the neutered MS RC4 encryption type, 2068 * set the trailing 9 bytes to 0xab per the 2069 * RC4-HMAC spec. 2070 */ 2071 if (tmi->enc_data.method == CRYPT_METHOD_ARCFOUR_HMAC_MD5_EXP) { 2072 bcopy((void *)&k1data[7], ms_exp, sizeof (ms_exp)); 2073 } 2074 2075 /* 2076 * Get the confounder bytes. 2077 */ 2078 (void) random_get_pseudo_bytes( 2079 (uint8_t *)(mp->b_rptr + hash->hash_len), 2080 (size_t)hash->confound_len); 2081 2082 k2.ck_data = k2data; 2083 k2.ck_format = CRYPTO_KEY_RAW; 2084 k2.ck_length = sizeof (k2data) * 8; 2085 2086 /* 2087 * This writes the HMAC to the hash area in the 2088 * mblk. The key used is the one just created by 2089 * the previous HMAC operation. 2090 * The data being processed is the confounder bytes 2091 * PLUS the input plaintext. 2092 */ 2093 result = do_hmac(md5_hmac_mech, &k2, 2094 (char *)mp->b_rptr + hash->hash_len, 2095 hash->confound_len + inlen, 2096 (char *)mp->b_rptr, hash->hash_len); 2097 if (result != CRYPTO_SUCCESS) { 2098 cmn_err(CE_WARN, 2099 "arcfour_hmac_md5_encrypt: do_hmac(k2)" 2100 "failed - error %0x", result); 2101 goto cleanup; 2102 } 2103 /* 2104 * Because of the odd way that MIT uses RC4 keys 2105 * on the rlogin stream, we only need to create 2106 * this key once. 2107 * However, if using "old" rcmd mode, we need to do 2108 * it every time. 2109 */ 2110 if (tmi->enc_data.ctx == NULL || 2111 (tmi->enc_data.option_mask & CRYPTOPT_RCMD_MODE_V1)) { 2112 crypto_key_t *key = &tmi->enc_data.d_encr_key; 2113 2114 k1.ck_data = k1data; 2115 k1.ck_format = CRYPTO_KEY_RAW; 2116 k1.ck_length = sizeof (k1data) * 8; 2117 2118 key->ck_format = CRYPTO_KEY_RAW; 2119 key->ck_length = k1.ck_length; 2120 if (key->ck_data == NULL) 2121 key->ck_data = kmem_zalloc( 2122 CRYPT_ARCFOUR_KEYBYTES, KM_SLEEP); 2123 2124 /* 2125 * The final HMAC operation creates the encryption 2126 * key to be used for the encrypt operation. 2127 */ 2128 result = do_hmac(md5_hmac_mech, &k1, 2129 (char *)mp->b_rptr, hash->hash_len, 2130 (char *)key->ck_data, CRYPT_ARCFOUR_KEYBYTES); 2131 2132 if (result != CRYPTO_SUCCESS) { 2133 cmn_err(CE_WARN, 2134 "arcfour_hmac_md5_encrypt: do_hmac(k3)" 2135 "failed - error %0x", result); 2136 goto cleanup; 2137 } 2138 } 2139 2140 /* 2141 * If the context has not been initialized, do it now. 2142 */ 2143 if (tmi->enc_data.ctx == NULL && 2144 (tmi->enc_data.option_mask & CRYPTOPT_RCMD_MODE_V2)) { 2145 /* 2146 * Only create a template if we are doing 2147 * chaining from block to block. 2148 */ 2149 result = crypto_create_ctx_template(&mech, 2150 &tmi->enc_data.d_encr_key, 2151 &tmi->enc_data.enc_tmpl, 2152 KM_SLEEP); 2153 if (result == CRYPTO_NOT_SUPPORTED) { 2154 tmi->enc_data.enc_tmpl = NULL; 2155 } else if (result != CRYPTO_SUCCESS) { 2156 cmn_err(CE_WARN, "failed to create enc template " 2157 "for RC4 encrypt: %0x", result); 2158 goto cleanup; 2159 } 2160 2161 result = crypto_encrypt_init(&mech, 2162 &tmi->enc_data.d_encr_key, 2163 tmi->enc_data.enc_tmpl, 2164 &tmi->enc_data.ctx, NULL); 2165 if (result != CRYPTO_SUCCESS) { 2166 cmn_err(CE_WARN, "crypto_encrypt_init failed:" 2167 " %0x", result); 2168 goto cleanup; 2169 } 2170 } 2171 v1.iov_base = (char *)mp->b_rptr + hash->hash_len; 2172 v1.iov_len = hash->confound_len + inlen; 2173 2174 indata.cd_format = CRYPTO_DATA_RAW; 2175 indata.cd_offset = 0; 2176 indata.cd_length = hash->confound_len + inlen; 2177 indata.cd_raw = v1; 2178 2179 if (tmi->enc_data.option_mask & CRYPTOPT_RCMD_MODE_V2) 2180 result = crypto_encrypt_update(tmi->enc_data.ctx, 2181 &indata, NULL, NULL); 2182 else 2183 result = crypto_encrypt(&mech, &indata, 2184 &tmi->enc_data.d_encr_key, NULL, 2185 NULL, NULL); 2186 2187 if (result != CRYPTO_SUCCESS) { 2188 cmn_err(CE_WARN, "crypto_encrypt_update failed: 0x%0x", 2189 result); 2190 } 2191 2192 cleanup: 2193 bzero(k1data, sizeof (k1data)); 2194 bzero(k2data, sizeof (k2data)); 2195 bzero(saltdata, sizeof (saltdata)); 2196 if (result != CRYPTO_SUCCESS) { 2197 mp->b_datap->db_type = M_ERROR; 2198 mp->b_rptr = mp->b_datap->db_base; 2199 *mp->b_rptr = EIO; 2200 mp->b_wptr = mp->b_rptr + sizeof (char); 2201 freemsg(mp->b_cont); 2202 mp->b_cont = NULL; 2203 qreply(WR(q), mp); 2204 return (NULL); 2205 } 2206 return (mp); 2207 } 2208 2209 /* 2210 * DES-CBC-[HASH] encrypt 2211 * 2212 * Needed to support userland apps that must support Kerberos V5 2213 * encryption DES-CBC encryption modes. 2214 * 2215 * The HASH values supported are RAW(NULL), MD5, CRC32, and SHA1 2216 * 2217 * format of ciphertext for DES-CBC functions, per RFC1510 is: 2218 * +-----------+----------+-------------+-----+ 2219 * |confounder | cksum | msg-data | pad | 2220 * +-----------+----------+-------------+-----+ 2221 * 2222 * format of ciphertext when using DES3-SHA1-HMAC 2223 * +-----------+----------+-------------+-----+ 2224 * |confounder | msg-data | hmac | pad | 2225 * +-----------+----------+-------------+-----+ 2226 * 2227 * The confounder is 8 bytes of random data. 2228 * The cksum depends on the hash being used. 2229 * 4 bytes for CRC32 2230 * 16 bytes for MD5 2231 * 20 bytes for SHA1 2232 * 0 bytes for RAW 2233 * 2234 */ 2235 static mblk_t * 2236 des_cbc_encrypt(queue_t *q, struct tmodinfo *tmi, mblk_t *mp, hash_info_t *hash) 2237 { 2238 int result; 2239 size_t cipherlen; 2240 size_t inlen; 2241 size_t plainlen; 2242 2243 /* 2244 * The size at this point should be the size of 2245 * all the plaintext plus the optional plaintext length 2246 * needed for RCMD V2 mode. There should also be room 2247 * at the head of the mblk for the confounder and hash info. 2248 */ 2249 inlen = (size_t)MBLKL(mp); 2250 2251 /* 2252 * The output size will be a multiple of 8 because this algorithm 2253 * only works on 8 byte chunks. 2254 */ 2255 cipherlen = encrypt_size(&tmi->enc_data, inlen); 2256 2257 ASSERT(MBLKSIZE(mp) >= cipherlen); 2258 2259 if (cipherlen > inlen) { 2260 bzero(mp->b_wptr, MBLKTAIL(mp)); 2261 } 2262 2263 /* 2264 * Shift the rptr back enough to insert 2265 * the confounder and hash. 2266 */ 2267 if (tmi->enc_data.method == CRYPT_METHOD_DES3_CBC_SHA1) { 2268 mp->b_rptr -= hash->confound_len; 2269 } else { 2270 mp->b_rptr -= (hash->confound_len + hash->hash_len); 2271 2272 /* zero out the hash area */ 2273 bzero(mp->b_rptr + hash->confound_len, (size_t)hash->hash_len); 2274 } 2275 2276 /* get random confounder from our friend, the 'random' module */ 2277 if (hash->confound_len > 0) { 2278 (void) random_get_pseudo_bytes((uint8_t *)mp->b_rptr, 2279 (size_t)hash->confound_len); 2280 } 2281 2282 /* 2283 * For 3DES we calculate an HMAC later. 2284 */ 2285 if (tmi->enc_data.method != CRYPT_METHOD_DES3_CBC_SHA1) { 2286 /* calculate chksum of confounder + input */ 2287 if (hash->hash_len > 0 && hash->hashfunc != NULL) { 2288 uchar_t cksum[MAX_CKSUM_LEN]; 2289 2290 result = hash->hashfunc(cksum, mp->b_rptr, 2291 cipherlen); 2292 if (result != CRYPTO_SUCCESS) { 2293 goto failure; 2294 } 2295 2296 /* put hash in place right after the confounder */ 2297 bcopy(cksum, (mp->b_rptr + hash->confound_len), 2298 (size_t)hash->hash_len); 2299 } 2300 } 2301 /* 2302 * In order to support the "old" Kerberos RCMD protocol, 2303 * we must use the IVEC 3 different ways: 2304 * IVEC_REUSE = keep using the same IV each time, this is 2305 * ugly and insecure, but necessary for 2306 * backwards compatibility with existing MIT code. 2307 * IVEC_ONETIME = Use the ivec as initialized when the crypto 2308 * was setup (see setup_crypto routine). 2309 * IVEC_NEVER = never use an IVEC, use a bunch of 0's as the IV (yuk). 2310 */ 2311 if (tmi->enc_data.ivec_usage == IVEC_NEVER) { 2312 bzero(tmi->enc_data.block, tmi->enc_data.blocklen); 2313 } else if (tmi->enc_data.ivec_usage == IVEC_REUSE) { 2314 bcopy(tmi->enc_data.ivec, tmi->enc_data.block, 2315 tmi->enc_data.blocklen); 2316 } 2317 2318 if (tmi->enc_data.method == CRYPT_METHOD_DES3_CBC_SHA1) { 2319 /* 2320 * The input length already included the hash size, 2321 * don't include this in the plaintext length 2322 * calculations. 2323 */ 2324 plainlen = cipherlen - hash->hash_len; 2325 2326 mp->b_wptr = mp->b_rptr + plainlen; 2327 2328 result = kef_encr_hmac(&tmi->enc_data, 2329 (void *)mp, (size_t)plainlen, 2330 (char *)(mp->b_rptr + plainlen), 2331 hash->hash_len); 2332 } else { 2333 ASSERT(mp->b_rptr + cipherlen <= DB_LIM(mp)); 2334 mp->b_wptr = mp->b_rptr + cipherlen; 2335 result = kef_crypt(&tmi->enc_data, (void *)mp, 2336 CRYPTO_DATA_MBLK, (size_t)cipherlen, 2337 CRYPT_ENCRYPT); 2338 } 2339 failure: 2340 if (result != CRYPTO_SUCCESS) { 2341 #ifdef DEBUG 2342 cmn_err(CE_WARN, 2343 "des_cbc_encrypt: kef_crypt encrypt " 2344 "failed (len: %ld) - error %0x", 2345 cipherlen, result); 2346 #endif 2347 mp->b_datap->db_type = M_ERROR; 2348 mp->b_rptr = mp->b_datap->db_base; 2349 *mp->b_rptr = EIO; 2350 mp->b_wptr = mp->b_rptr + sizeof (char); 2351 freemsg(mp->b_cont); 2352 mp->b_cont = NULL; 2353 qreply(WR(q), mp); 2354 return (NULL); 2355 } else if (tmi->enc_data.ivec_usage == IVEC_ONETIME) { 2356 /* 2357 * Because we are using KEF, we must manually 2358 * update our IV. 2359 */ 2360 bcopy(mp->b_wptr - tmi->enc_data.ivlen, 2361 tmi->enc_data.block, tmi->enc_data.ivlen); 2362 } 2363 if (tmi->enc_data.method == CRYPT_METHOD_DES3_CBC_SHA1) { 2364 mp->b_wptr = mp->b_rptr + cipherlen; 2365 } 2366 2367 return (mp); 2368 } 2369 2370 /* 2371 * des_cbc_decrypt 2372 * 2373 * 2374 * Needed to support userland apps that must support Kerberos V5 2375 * encryption DES-CBC decryption modes. 2376 * 2377 * The HASH values supported are RAW(NULL), MD5, CRC32, and SHA1 2378 * 2379 * format of ciphertext for DES-CBC functions, per RFC1510 is: 2380 * +-----------+----------+-------------+-----+ 2381 * |confounder | cksum | msg-data | pad | 2382 * +-----------+----------+-------------+-----+ 2383 * 2384 * format of ciphertext when using DES3-SHA1-HMAC 2385 * +-----------+----------+-------------+-----+ 2386 * |confounder | msg-data | hmac | pad | 2387 * +-----------+----------+-------------+-----+ 2388 * 2389 * The confounder is 8 bytes of random data. 2390 * The cksum depends on the hash being used. 2391 * 4 bytes for CRC32 2392 * 16 bytes for MD5 2393 * 20 bytes for SHA1 2394 * 0 bytes for RAW 2395 * 2396 */ 2397 static mblk_t * 2398 des_cbc_decrypt(queue_t *q, struct tmodinfo *tmi, mblk_t *mp, hash_info_t *hash) 2399 { 2400 uint_t inlen, datalen; 2401 int result = 0; 2402 uchar_t *optr = NULL; 2403 uchar_t cksum[MAX_CKSUM_LEN], newcksum[MAX_CKSUM_LEN]; 2404 uchar_t nextiv[DEFAULT_DES_BLOCKLEN]; 2405 2406 /* Compute adjusted size */ 2407 inlen = MBLKL(mp); 2408 2409 optr = mp->b_rptr; 2410 2411 /* 2412 * In order to support the "old" Kerberos RCMD protocol, 2413 * we must use the IVEC 3 different ways: 2414 * IVEC_REUSE = keep using the same IV each time, this is 2415 * ugly and insecure, but necessary for 2416 * backwards compatibility with existing MIT code. 2417 * IVEC_ONETIME = Use the ivec as initialized when the crypto 2418 * was setup (see setup_crypto routine). 2419 * IVEC_NEVER = never use an IVEC, use a bunch of 0's as the IV (yuk). 2420 */ 2421 if (tmi->dec_data.ivec_usage == IVEC_NEVER) 2422 bzero(tmi->dec_data.block, tmi->dec_data.blocklen); 2423 else if (tmi->dec_data.ivec_usage == IVEC_REUSE) 2424 bcopy(tmi->dec_data.ivec, tmi->dec_data.block, 2425 tmi->dec_data.blocklen); 2426 2427 if (tmi->dec_data.method == CRYPT_METHOD_DES3_CBC_SHA1) { 2428 /* 2429 * Do not decrypt the HMAC at the end 2430 */ 2431 int decrypt_len = inlen - hash->hash_len; 2432 2433 /* 2434 * Move the wptr so the mblk appears to end 2435 * BEFORE the HMAC section. 2436 */ 2437 mp->b_wptr = mp->b_rptr + decrypt_len; 2438 2439 /* 2440 * Because we are using KEF, we must manually update our 2441 * IV. 2442 */ 2443 if (tmi->dec_data.ivec_usage == IVEC_ONETIME) { 2444 bcopy(mp->b_rptr + decrypt_len - tmi->dec_data.ivlen, 2445 nextiv, tmi->dec_data.ivlen); 2446 } 2447 2448 result = kef_decr_hmac(&tmi->dec_data, mp, decrypt_len, 2449 (char *)newcksum, hash->hash_len); 2450 } else { 2451 /* 2452 * Because we are using KEF, we must manually update our 2453 * IV. 2454 */ 2455 if (tmi->dec_data.ivec_usage == IVEC_ONETIME) { 2456 bcopy(mp->b_wptr - tmi->enc_data.ivlen, nextiv, 2457 tmi->dec_data.ivlen); 2458 } 2459 result = kef_crypt(&tmi->dec_data, (void *)mp, 2460 CRYPTO_DATA_MBLK, (size_t)inlen, CRYPT_DECRYPT); 2461 } 2462 if (result != CRYPTO_SUCCESS) { 2463 #ifdef DEBUG 2464 cmn_err(CE_WARN, 2465 "des_cbc_decrypt: kef_crypt decrypt " 2466 "failed - error %0x", result); 2467 #endif 2468 mp->b_datap->db_type = M_ERROR; 2469 mp->b_rptr = mp->b_datap->db_base; 2470 *mp->b_rptr = EIO; 2471 mp->b_wptr = mp->b_rptr + sizeof (char); 2472 freemsg(mp->b_cont); 2473 mp->b_cont = NULL; 2474 qreply(WR(q), mp); 2475 return (NULL); 2476 } 2477 2478 /* 2479 * Manually update the IV, KEF does not track this for us. 2480 */ 2481 if (tmi->dec_data.ivec_usage == IVEC_ONETIME) { 2482 bcopy(nextiv, tmi->dec_data.block, tmi->dec_data.ivlen); 2483 } 2484 2485 /* Verify the checksum(if necessary) */ 2486 if (hash->hash_len > 0) { 2487 if (tmi->dec_data.method == CRYPT_METHOD_DES3_CBC_SHA1) { 2488 bcopy(mp->b_rptr + inlen - hash->hash_len, cksum, 2489 hash->hash_len); 2490 } else { 2491 bcopy(optr + hash->confound_len, cksum, hash->hash_len); 2492 2493 /* zero the cksum in the buffer */ 2494 ASSERT(optr + hash->confound_len + hash->hash_len <= 2495 DB_LIM(mp)); 2496 bzero(optr + hash->confound_len, hash->hash_len); 2497 2498 /* calculate MD5 chksum of confounder + input */ 2499 if (hash->hashfunc) { 2500 (void) hash->hashfunc(newcksum, optr, inlen); 2501 } 2502 } 2503 2504 if (bcmp(cksum, newcksum, hash->hash_len)) { 2505 #ifdef DEBUG 2506 cmn_err(CE_WARN, "des_cbc_decrypt: checksum " 2507 "verification failed"); 2508 #endif 2509 mp->b_datap->db_type = M_ERROR; 2510 mp->b_rptr = mp->b_datap->db_base; 2511 *mp->b_rptr = EIO; 2512 mp->b_wptr = mp->b_rptr + sizeof (char); 2513 freemsg(mp->b_cont); 2514 mp->b_cont = NULL; 2515 qreply(WR(q), mp); 2516 return (NULL); 2517 } 2518 } 2519 2520 datalen = inlen - hash->confound_len - hash->hash_len; 2521 2522 /* Move just the decrypted input into place if necessary */ 2523 if (hash->confound_len > 0 || hash->hash_len > 0) { 2524 if (tmi->dec_data.method == CRYPT_METHOD_DES3_CBC_SHA1) 2525 mp->b_rptr += hash->confound_len; 2526 else 2527 mp->b_rptr += hash->confound_len + hash->hash_len; 2528 } 2529 2530 ASSERT(mp->b_rptr + datalen <= DB_LIM(mp)); 2531 mp->b_wptr = mp->b_rptr + datalen; 2532 2533 return (mp); 2534 } 2535 2536 static mblk_t * 2537 do_decrypt(queue_t *q, mblk_t *mp) 2538 { 2539 struct tmodinfo *tmi = (struct tmodinfo *)q->q_ptr; 2540 mblk_t *outmp; 2541 2542 switch (tmi->dec_data.method) { 2543 case CRYPT_METHOD_DES_CFB: 2544 outmp = des_cfb_decrypt(q, tmi, mp); 2545 break; 2546 case CRYPT_METHOD_NONE: 2547 outmp = mp; 2548 break; 2549 case CRYPT_METHOD_DES_CBC_NULL: 2550 outmp = des_cbc_decrypt(q, tmi, mp, &null_hash); 2551 break; 2552 case CRYPT_METHOD_DES_CBC_MD5: 2553 outmp = des_cbc_decrypt(q, tmi, mp, &md5_hash); 2554 break; 2555 case CRYPT_METHOD_DES_CBC_CRC: 2556 outmp = des_cbc_decrypt(q, tmi, mp, &crc32_hash); 2557 break; 2558 case CRYPT_METHOD_DES3_CBC_SHA1: 2559 outmp = des_cbc_decrypt(q, tmi, mp, &sha1_hash); 2560 break; 2561 case CRYPT_METHOD_ARCFOUR_HMAC_MD5: 2562 case CRYPT_METHOD_ARCFOUR_HMAC_MD5_EXP: 2563 outmp = arcfour_hmac_md5_decrypt(q, tmi, mp, &md5_hash); 2564 break; 2565 case CRYPT_METHOD_AES128: 2566 case CRYPT_METHOD_AES256: 2567 outmp = aes_decrypt(q, tmi, mp, &sha1_hash); 2568 break; 2569 } 2570 return (outmp); 2571 } 2572 2573 /* 2574 * do_encrypt 2575 * 2576 * Generic encryption routine for a single message block. 2577 * The input mblk may be replaced by some encrypt routines 2578 * because they add extra data in some cases that may exceed 2579 * the input mblk_t size limit. 2580 */ 2581 static mblk_t * 2582 do_encrypt(queue_t *q, mblk_t *mp) 2583 { 2584 struct tmodinfo *tmi = (struct tmodinfo *)q->q_ptr; 2585 mblk_t *outmp; 2586 2587 switch (tmi->enc_data.method) { 2588 case CRYPT_METHOD_DES_CFB: 2589 outmp = des_cfb_encrypt(q, tmi, mp); 2590 break; 2591 case CRYPT_METHOD_DES_CBC_NULL: 2592 outmp = des_cbc_encrypt(q, tmi, mp, &null_hash); 2593 break; 2594 case CRYPT_METHOD_DES_CBC_MD5: 2595 outmp = des_cbc_encrypt(q, tmi, mp, &md5_hash); 2596 break; 2597 case CRYPT_METHOD_DES_CBC_CRC: 2598 outmp = des_cbc_encrypt(q, tmi, mp, &crc32_hash); 2599 break; 2600 case CRYPT_METHOD_DES3_CBC_SHA1: 2601 outmp = des_cbc_encrypt(q, tmi, mp, &sha1_hash); 2602 break; 2603 case CRYPT_METHOD_ARCFOUR_HMAC_MD5: 2604 case CRYPT_METHOD_ARCFOUR_HMAC_MD5_EXP: 2605 outmp = arcfour_hmac_md5_encrypt(q, tmi, mp, &md5_hash); 2606 break; 2607 case CRYPT_METHOD_AES128: 2608 case CRYPT_METHOD_AES256: 2609 outmp = aes_encrypt(q, tmi, mp, &sha1_hash); 2610 break; 2611 case CRYPT_METHOD_NONE: 2612 outmp = mp; 2613 break; 2614 } 2615 return (outmp); 2616 } 2617 2618 /* 2619 * setup_crypto 2620 * 2621 * This takes the data from the CRYPTIOCSETUP ioctl 2622 * and sets up a cipher_data_t structure for either 2623 * encryption or decryption. This is where the 2624 * key and initialization vector data get stored 2625 * prior to beginning any crypto functions. 2626 * 2627 * Special note: 2628 * Some applications(e.g. telnetd) have ability to switch 2629 * crypto on/off periodically. Thus, the application may call 2630 * the CRYPTIOCSETUP ioctl many times for the same stream. 2631 * If the CRYPTIOCSETUP is called with 0 length key or ivec fields 2632 * assume that the key, block, and saveblock fields that are already 2633 * set from a previous CRIOCSETUP call are still valid. This helps avoid 2634 * a rekeying error that could occur if we overwrite these fields 2635 * with each CRYPTIOCSETUP call. 2636 * In short, sometimes, CRYPTIOCSETUP is used to simply toggle on/off 2637 * without resetting the original crypto parameters. 2638 * 2639 */ 2640 static int 2641 setup_crypto(struct cr_info_t *ci, struct cipher_data_t *cd, int encrypt) 2642 { 2643 uint_t newblocklen; 2644 uint32_t enc_usage = 0, dec_usage = 0; 2645 int rv; 2646 2647 /* 2648 * Initial sanity checks 2649 */ 2650 if (!CR_METHOD_OK(ci->crypto_method)) { 2651 cmn_err(CE_WARN, "Illegal crypto method (%d)", 2652 ci->crypto_method); 2653 return (EINVAL); 2654 } 2655 if (!CR_OPTIONS_OK(ci->option_mask)) { 2656 cmn_err(CE_WARN, "Illegal crypto options (%d)", 2657 ci->option_mask); 2658 return (EINVAL); 2659 } 2660 if (!CR_IVUSAGE_OK(ci->ivec_usage)) { 2661 cmn_err(CE_WARN, "Illegal ivec usage value (%d)", 2662 ci->ivec_usage); 2663 return (EINVAL); 2664 } 2665 2666 cd->method = ci->crypto_method; 2667 cd->bytes = 0; 2668 2669 if (ci->keylen > 0) { 2670 if (cd->key != NULL) { 2671 kmem_free(cd->key, cd->keylen); 2672 cd->key = NULL; 2673 cd->keylen = 0; 2674 } 2675 /* 2676 * cd->key holds the copy of the raw key bytes passed in 2677 * from the userland app. 2678 */ 2679 cd->key = (char *)kmem_alloc((size_t)ci->keylen, KM_SLEEP); 2680 2681 cd->keylen = ci->keylen; 2682 bcopy(ci->key, cd->key, (size_t)ci->keylen); 2683 } 2684 2685 /* 2686 * Configure the block size based on the type of cipher. 2687 */ 2688 switch (cd->method) { 2689 case CRYPT_METHOD_NONE: 2690 newblocklen = 0; 2691 break; 2692 case CRYPT_METHOD_DES_CFB: 2693 newblocklen = DEFAULT_DES_BLOCKLEN; 2694 cd->mech_type = crypto_mech2id(SUN_CKM_DES_ECB); 2695 break; 2696 case CRYPT_METHOD_DES_CBC_NULL: 2697 case CRYPT_METHOD_DES_CBC_MD5: 2698 case CRYPT_METHOD_DES_CBC_CRC: 2699 newblocklen = DEFAULT_DES_BLOCKLEN; 2700 cd->mech_type = crypto_mech2id(SUN_CKM_DES_CBC); 2701 break; 2702 case CRYPT_METHOD_DES3_CBC_SHA1: 2703 newblocklen = DEFAULT_DES_BLOCKLEN; 2704 cd->mech_type = crypto_mech2id(SUN_CKM_DES3_CBC); 2705 /* 3DES always uses the old usage constant */ 2706 enc_usage = RCMDV1_USAGE; 2707 dec_usage = RCMDV1_USAGE; 2708 break; 2709 case CRYPT_METHOD_ARCFOUR_HMAC_MD5: 2710 case CRYPT_METHOD_ARCFOUR_HMAC_MD5_EXP: 2711 newblocklen = 0; 2712 cd->mech_type = crypto_mech2id(SUN_CKM_RC4); 2713 break; 2714 case CRYPT_METHOD_AES128: 2715 case CRYPT_METHOD_AES256: 2716 newblocklen = DEFAULT_AES_BLOCKLEN; 2717 cd->mech_type = crypto_mech2id(SUN_CKM_AES_ECB); 2718 enc_usage = AES_ENCRYPT_USAGE; 2719 dec_usage = AES_DECRYPT_USAGE; 2720 break; 2721 } 2722 if (cd->mech_type == CRYPTO_MECH_INVALID) { 2723 return (CRYPTO_FAILED); 2724 } 2725 2726 /* 2727 * If RC4, initialize the master crypto key used by 2728 * the RC4 algorithm to derive the final encrypt and decrypt keys. 2729 */ 2730 if (cd->keylen > 0 && IS_RC4_METHOD(cd->method)) { 2731 /* 2732 * cd->ckey is a kernel crypto key structure used as the 2733 * master key in the RC4-HMAC crypto operations. 2734 */ 2735 if (cd->ckey == NULL) { 2736 cd->ckey = (crypto_key_t *)kmem_zalloc( 2737 sizeof (crypto_key_t), KM_SLEEP); 2738 } 2739 2740 cd->ckey->ck_format = CRYPTO_KEY_RAW; 2741 cd->ckey->ck_data = cd->key; 2742 2743 /* key length for EF is measured in bits */ 2744 cd->ckey->ck_length = cd->keylen * 8; 2745 } 2746 2747 /* 2748 * cd->block and cd->saveblock are used as temporary storage for 2749 * data that must be carried over between encrypt/decrypt operations 2750 * in some of the "feedback" modes. 2751 */ 2752 if (newblocklen != cd->blocklen) { 2753 if (cd->block != NULL) { 2754 kmem_free(cd->block, cd->blocklen); 2755 cd->block = NULL; 2756 } 2757 2758 if (cd->saveblock != NULL) { 2759 kmem_free(cd->saveblock, cd->blocklen); 2760 cd->saveblock = NULL; 2761 } 2762 2763 cd->blocklen = newblocklen; 2764 if (cd->blocklen) { 2765 cd->block = (char *)kmem_zalloc((size_t)cd->blocklen, 2766 KM_SLEEP); 2767 } 2768 2769 if (cd->method == CRYPT_METHOD_DES_CFB) 2770 cd->saveblock = (char *)kmem_zalloc(cd->blocklen, 2771 KM_SLEEP); 2772 else 2773 cd->saveblock = NULL; 2774 } 2775 2776 if (ci->iveclen != cd->ivlen) { 2777 if (cd->ivec != NULL) { 2778 kmem_free(cd->ivec, cd->ivlen); 2779 cd->ivec = NULL; 2780 } 2781 if (ci->ivec_usage != IVEC_NEVER && ci->iveclen > 0) { 2782 cd->ivec = (char *)kmem_zalloc((size_t)ci->iveclen, 2783 KM_SLEEP); 2784 cd->ivlen = ci->iveclen; 2785 } else { 2786 cd->ivlen = 0; 2787 cd->ivec = NULL; 2788 } 2789 } 2790 cd->option_mask = ci->option_mask; 2791 2792 /* 2793 * Old protocol requires a static 'usage' value for 2794 * deriving keys. Yuk. 2795 */ 2796 if (cd->option_mask & CRYPTOPT_RCMD_MODE_V1) { 2797 enc_usage = dec_usage = RCMDV1_USAGE; 2798 } 2799 2800 if (cd->ivlen > cd->blocklen) { 2801 cmn_err(CE_WARN, "setup_crypto: IV longer than block size"); 2802 return (EINVAL); 2803 } 2804 2805 /* 2806 * If we are using an IVEC "correctly" (i.e. set it once) 2807 * copy it here. 2808 */ 2809 if (ci->ivec_usage == IVEC_ONETIME && cd->block != NULL) 2810 bcopy(ci->ivec, cd->block, (size_t)cd->ivlen); 2811 2812 cd->ivec_usage = ci->ivec_usage; 2813 if (cd->ivec != NULL) { 2814 /* Save the original IVEC in case we need it later */ 2815 bcopy(ci->ivec, cd->ivec, (size_t)cd->ivlen); 2816 } 2817 /* 2818 * Special handling for 3DES-SHA1-HMAC and AES crypto: 2819 * generate derived keys and context templates 2820 * for better performance. 2821 */ 2822 if (cd->method == CRYPT_METHOD_DES3_CBC_SHA1 || 2823 IS_AES_METHOD(cd->method)) { 2824 crypto_mechanism_t enc_mech; 2825 crypto_mechanism_t hmac_mech; 2826 2827 if (cd->d_encr_key.ck_data != NULL) { 2828 bzero(cd->d_encr_key.ck_data, cd->keylen); 2829 kmem_free(cd->d_encr_key.ck_data, cd->keylen); 2830 } 2831 2832 if (cd->d_hmac_key.ck_data != NULL) { 2833 bzero(cd->d_hmac_key.ck_data, cd->keylen); 2834 kmem_free(cd->d_hmac_key.ck_data, cd->keylen); 2835 } 2836 2837 if (cd->enc_tmpl != NULL) 2838 (void) crypto_destroy_ctx_template(cd->enc_tmpl); 2839 2840 if (cd->hmac_tmpl != NULL) 2841 (void) crypto_destroy_ctx_template(cd->hmac_tmpl); 2842 2843 enc_mech.cm_type = cd->mech_type; 2844 enc_mech.cm_param = cd->ivec; 2845 enc_mech.cm_param_len = cd->ivlen; 2846 2847 hmac_mech.cm_type = sha1_hmac_mech; 2848 hmac_mech.cm_param = NULL; 2849 hmac_mech.cm_param_len = 0; 2850 2851 /* 2852 * Create the derived keys. 2853 */ 2854 rv = create_derived_keys(cd, 2855 (encrypt ? enc_usage : dec_usage), 2856 &cd->d_encr_key, &cd->d_hmac_key); 2857 2858 if (rv != CRYPTO_SUCCESS) { 2859 cmn_err(CE_WARN, "failed to create derived " 2860 "keys: %0x", rv); 2861 return (CRYPTO_FAILED); 2862 } 2863 2864 rv = crypto_create_ctx_template(&enc_mech, 2865 &cd->d_encr_key, 2866 &cd->enc_tmpl, KM_SLEEP); 2867 if (rv == CRYPTO_MECH_NOT_SUPPORTED) { 2868 cd->enc_tmpl = NULL; 2869 } else if (rv != CRYPTO_SUCCESS) { 2870 cmn_err(CE_WARN, "failed to create enc template " 2871 "for d_encr_key: %0x", rv); 2872 return (CRYPTO_FAILED); 2873 } 2874 2875 rv = crypto_create_ctx_template(&hmac_mech, 2876 &cd->d_hmac_key, 2877 &cd->hmac_tmpl, KM_SLEEP); 2878 if (rv == CRYPTO_MECH_NOT_SUPPORTED) { 2879 cd->hmac_tmpl = NULL; 2880 } else if (rv != CRYPTO_SUCCESS) { 2881 cmn_err(CE_WARN, "failed to create hmac template:" 2882 " %0x", rv); 2883 return (CRYPTO_FAILED); 2884 } 2885 } else if (IS_RC4_METHOD(cd->method)) { 2886 bzero(&cd->d_encr_key, sizeof (crypto_key_t)); 2887 bzero(&cd->d_hmac_key, sizeof (crypto_key_t)); 2888 cd->ctx = NULL; 2889 cd->enc_tmpl = NULL; 2890 cd->hmac_tmpl = NULL; 2891 } 2892 2893 /* Final sanity checks, make sure no fields are NULL */ 2894 if (cd->method != CRYPT_METHOD_NONE) { 2895 if (cd->block == NULL && cd->blocklen > 0) { 2896 #ifdef DEBUG 2897 cmn_err(CE_WARN, 2898 "setup_crypto: IV block not allocated"); 2899 #endif 2900 return (ENOMEM); 2901 } 2902 if (cd->key == NULL && cd->keylen > 0) { 2903 #ifdef DEBUG 2904 cmn_err(CE_WARN, 2905 "setup_crypto: key block not allocated"); 2906 #endif 2907 return (ENOMEM); 2908 } 2909 if (cd->method == CRYPT_METHOD_DES_CFB && 2910 cd->saveblock == NULL && cd->blocklen > 0) { 2911 #ifdef DEBUG 2912 cmn_err(CE_WARN, 2913 "setup_crypto: save block not allocated"); 2914 #endif 2915 return (ENOMEM); 2916 } 2917 if (cd->ivec == NULL && cd->ivlen > 0) { 2918 #ifdef DEBUG 2919 cmn_err(CE_WARN, 2920 "setup_crypto: IV not allocated"); 2921 #endif 2922 return (ENOMEM); 2923 } 2924 } 2925 return (0); 2926 } 2927 2928 /* 2929 * RCMDS require a 4 byte, clear text 2930 * length field before each message. 2931 * Add it now. 2932 */ 2933 static mblk_t * 2934 mklenmp(mblk_t *bp, uint32_t len) 2935 { 2936 mblk_t *lenmp; 2937 uchar_t *ucp; 2938 2939 if (bp->b_rptr - 4 < DB_BASE(bp) || DB_REF(bp) > 1) { 2940 lenmp = allocb(4, BPRI_MED); 2941 if (lenmp != NULL) { 2942 lenmp->b_rptr = lenmp->b_wptr = DB_LIM(lenmp); 2943 linkb(lenmp, bp); 2944 bp = lenmp; 2945 } 2946 } 2947 ucp = bp->b_rptr; 2948 *--ucp = len; 2949 *--ucp = len >> 8; 2950 *--ucp = len >> 16; 2951 *--ucp = len >> 24; 2952 2953 bp->b_rptr = ucp; 2954 2955 return (bp); 2956 } 2957 2958 static mblk_t * 2959 encrypt_block(queue_t *q, struct tmodinfo *tmi, mblk_t *mp, size_t plainlen) 2960 { 2961 mblk_t *newmp; 2962 size_t headspace; 2963 2964 mblk_t *cbp; 2965 size_t cipherlen; 2966 size_t extra = 0; 2967 uint32_t ptlen = (uint32_t)plainlen; 2968 /* 2969 * If we are using the "NEW" RCMD mode, 2970 * add 4 bytes to the plaintext for the 2971 * plaintext length that gets prepended 2972 * before encrypting. 2973 */ 2974 if (tmi->enc_data.option_mask & CRYPTOPT_RCMD_MODE_V2) 2975 ptlen += 4; 2976 2977 cipherlen = encrypt_size(&tmi->enc_data, (size_t)ptlen); 2978 2979 /* 2980 * if we must allocb, then make sure its enough 2981 * to hold the length field so we dont have to allocb 2982 * again down below in 'mklenmp' 2983 */ 2984 if (ANY_RCMD_MODE(tmi->enc_data.option_mask)) { 2985 extra = sizeof (uint32_t); 2986 } 2987 2988 /* 2989 * Calculate how much space is needed in front of 2990 * the data. 2991 */ 2992 headspace = plaintext_offset(&tmi->enc_data); 2993 2994 /* 2995 * If the current block is too small, reallocate 2996 * one large enough to hold the hdr, tail, and 2997 * ciphertext. 2998 */ 2999 if ((cipherlen + extra >= MBLKSIZE(mp)) || DB_REF(mp) > 1) { 3000 int sz = P2ROUNDUP(cipherlen+extra, 8); 3001 3002 cbp = allocb_tmpl(sz, mp); 3003 if (cbp == NULL) { 3004 cmn_err(CE_WARN, 3005 "allocb (%d bytes) failed", sz); 3006 return (NULL); 3007 } 3008 3009 cbp->b_cont = mp->b_cont; 3010 3011 /* 3012 * headspace includes the length fields needed 3013 * for the RCMD modes (v1 == 4 bytes, V2 = 8) 3014 */ 3015 ASSERT(cbp->b_rptr + P2ROUNDUP(plainlen+headspace, 8) 3016 <= DB_LIM(cbp)); 3017 3018 cbp->b_rptr = DB_BASE(cbp) + headspace; 3019 bcopy(mp->b_rptr, cbp->b_rptr, plainlen); 3020 cbp->b_wptr = cbp->b_rptr + plainlen; 3021 3022 freeb(mp); 3023 } else { 3024 size_t extra = 0; 3025 cbp = mp; 3026 3027 /* 3028 * Some ciphers add HMAC after the final block 3029 * of the ciphertext, not at the beginning like the 3030 * 1-DES ciphers. 3031 */ 3032 if (tmi->enc_data.method == 3033 CRYPT_METHOD_DES3_CBC_SHA1 || 3034 IS_AES_METHOD(tmi->enc_data.method)) { 3035 extra = sha1_hash.hash_len; 3036 } 3037 3038 /* 3039 * Make sure the rptr is positioned correctly so that 3040 * routines later do not have to shift this data around 3041 */ 3042 if ((cbp->b_rptr + P2ROUNDUP(cipherlen + extra, 8) > 3043 DB_LIM(cbp)) || 3044 (cbp->b_rptr - headspace < DB_BASE(cbp))) { 3045 ovbcopy(cbp->b_rptr, DB_BASE(cbp) + headspace, 3046 plainlen); 3047 cbp->b_rptr = DB_BASE(cbp) + headspace; 3048 cbp->b_wptr = cbp->b_rptr + plainlen; 3049 } 3050 } 3051 3052 ASSERT(cbp->b_rptr - headspace >= DB_BASE(cbp)); 3053 ASSERT(cbp->b_wptr <= DB_LIM(cbp)); 3054 3055 /* 3056 * If using RCMD_MODE_V2 (new rcmd mode), prepend 3057 * the plaintext length before the actual plaintext. 3058 */ 3059 if (tmi->enc_data.option_mask & CRYPTOPT_RCMD_MODE_V2) { 3060 cbp->b_rptr -= RCMD_LEN_SZ; 3061 3062 /* put plaintext length at head of buffer */ 3063 *(cbp->b_rptr + 3) = (uchar_t)(plainlen & 0xff); 3064 *(cbp->b_rptr + 2) = (uchar_t)((plainlen >> 8) & 0xff); 3065 *(cbp->b_rptr + 1) = (uchar_t)((plainlen >> 16) & 0xff); 3066 *(cbp->b_rptr) = (uchar_t)((plainlen >> 24) & 0xff); 3067 } 3068 3069 newmp = do_encrypt(q, cbp); 3070 3071 if (newmp != NULL && 3072 (tmi->enc_data.option_mask & 3073 (CRYPTOPT_RCMD_MODE_V1 | CRYPTOPT_RCMD_MODE_V2))) { 3074 mblk_t *lp; 3075 /* 3076 * Add length field, required when this is 3077 * used to encrypt "r*" commands(rlogin, rsh) 3078 * with Kerberos. 3079 */ 3080 lp = mklenmp(newmp, plainlen); 3081 3082 if (lp == NULL) { 3083 freeb(newmp); 3084 return (NULL); 3085 } else { 3086 newmp = lp; 3087 } 3088 } 3089 return (newmp); 3090 } 3091 3092 /* 3093 * encrypt_msgb 3094 * 3095 * encrypt a single message. This routine adds the 3096 * RCMD overhead bytes when necessary. 3097 */ 3098 static mblk_t * 3099 encrypt_msgb(queue_t *q, struct tmodinfo *tmi, mblk_t *mp) 3100 { 3101 size_t plainlen, outlen; 3102 mblk_t *newmp = NULL; 3103 3104 /* If not encrypting, do nothing */ 3105 if (tmi->enc_data.method == CRYPT_METHOD_NONE) { 3106 return (mp); 3107 } 3108 3109 plainlen = MBLKL(mp); 3110 if (plainlen == 0) 3111 return (NULL); 3112 3113 /* 3114 * If the block is too big, we encrypt in 4K chunks so that 3115 * older rlogin clients do not choke on the larger buffers. 3116 */ 3117 while ((plainlen = MBLKL(mp)) > MSGBUF_SIZE) { 3118 mblk_t *mp1 = NULL; 3119 outlen = MSGBUF_SIZE; 3120 /* 3121 * Allocate a new buffer that is only 4K bytes, the 3122 * extra bytes are for crypto overhead. 3123 */ 3124 mp1 = allocb(outlen + CONFOUNDER_BYTES, BPRI_MED); 3125 if (mp1 == NULL) { 3126 cmn_err(CE_WARN, 3127 "allocb (%d bytes) failed", 3128 (int)(outlen + CONFOUNDER_BYTES)); 3129 return (NULL); 3130 } 3131 /* Copy the next 4K bytes from the old block. */ 3132 bcopy(mp->b_rptr, mp1->b_rptr, outlen); 3133 mp1->b_wptr = mp1->b_rptr + outlen; 3134 /* Advance the old block. */ 3135 mp->b_rptr += outlen; 3136 3137 /* encrypt the new block */ 3138 newmp = encrypt_block(q, tmi, mp1, outlen); 3139 if (newmp == NULL) 3140 return (NULL); 3141 3142 putnext(q, newmp); 3143 } 3144 newmp = NULL; 3145 /* If there is data left (< MSGBUF_SIZE), encrypt it. */ 3146 if ((plainlen = MBLKL(mp)) > 0) 3147 newmp = encrypt_block(q, tmi, mp, plainlen); 3148 3149 return (newmp); 3150 } 3151 3152 /* 3153 * cryptmodwsrv 3154 * 3155 * Service routine for the write queue. 3156 * 3157 * Because data may be placed in the queue to hold between 3158 * the CRYPTIOCSTOP and CRYPTIOCSTART ioctls, the service routine is needed. 3159 */ 3160 static int 3161 cryptmodwsrv(queue_t *q) 3162 { 3163 mblk_t *mp; 3164 struct tmodinfo *tmi = (struct tmodinfo *)q->q_ptr; 3165 3166 while ((mp = getq(q)) != NULL) { 3167 switch (mp->b_datap->db_type) { 3168 default: 3169 /* 3170 * wput does not queue anything > QPCTL 3171 */ 3172 if (!canputnext(q) || 3173 !(tmi->ready & CRYPT_WRITE_READY)) { 3174 if (!putbq(q, mp)) { 3175 freemsg(mp); 3176 } 3177 return (0); 3178 } 3179 putnext(q, mp); 3180 break; 3181 case M_DATA: 3182 if (canputnext(q) && (tmi->ready & CRYPT_WRITE_READY)) { 3183 mblk_t *bp; 3184 mblk_t *newmsg = NULL; 3185 3186 /* 3187 * If multiple msgs, concat into 1 3188 * to minimize crypto operations later. 3189 */ 3190 if (mp->b_cont != NULL) { 3191 bp = msgpullup(mp, -1); 3192 if (bp != NULL) { 3193 freemsg(mp); 3194 mp = bp; 3195 } 3196 } 3197 newmsg = encrypt_msgb(q, tmi, mp); 3198 if (newmsg != NULL) 3199 putnext(q, newmsg); 3200 } else { 3201 if (!putbq(q, mp)) { 3202 freemsg(mp); 3203 } 3204 return (0); 3205 } 3206 break; 3207 } 3208 } 3209 return (0); 3210 } 3211 3212 static void 3213 start_stream(queue_t *wq, mblk_t *mp, uchar_t dir) 3214 { 3215 mblk_t *newmp = NULL; 3216 struct tmodinfo *tmi = (struct tmodinfo *)wq->q_ptr; 3217 3218 if (dir == CRYPT_ENCRYPT) { 3219 tmi->ready |= CRYPT_WRITE_READY; 3220 (void) (STRLOG(CRYPTMOD_ID, 0, 5, SL_TRACE|SL_NOTE, 3221 "start_stream: restart ENCRYPT/WRITE q")); 3222 3223 enableok(wq); 3224 qenable(wq); 3225 } else if (dir == CRYPT_DECRYPT) { 3226 /* 3227 * put any extra data in the RD 3228 * queue to be processed and 3229 * sent back up. 3230 */ 3231 newmp = mp->b_cont; 3232 mp->b_cont = NULL; 3233 3234 tmi->ready |= CRYPT_READ_READY; 3235 (void) (STRLOG(CRYPTMOD_ID, 0, 5, 3236 SL_TRACE|SL_NOTE, 3237 "start_stream: restart " 3238 "DECRYPT/READ q")); 3239 3240 if (newmp != NULL) 3241 if (!putbq(RD(wq), newmp)) 3242 freemsg(newmp); 3243 3244 enableok(RD(wq)); 3245 qenable(RD(wq)); 3246 } 3247 3248 miocack(wq, mp, 0, 0); 3249 } 3250 3251 /* 3252 * Write-side put procedure. Its main task is to detect ioctls and 3253 * FLUSH operations. Other message types are passed on through. 3254 */ 3255 static void 3256 cryptmodwput(queue_t *wq, mblk_t *mp) 3257 { 3258 struct iocblk *iocp; 3259 struct tmodinfo *tmi = (struct tmodinfo *)wq->q_ptr; 3260 int ret, err; 3261 3262 switch (mp->b_datap->db_type) { 3263 case M_DATA: 3264 if (wq->q_first == NULL && canputnext(wq) && 3265 (tmi->ready & CRYPT_WRITE_READY) && 3266 tmi->enc_data.method == CRYPT_METHOD_NONE) { 3267 putnext(wq, mp); 3268 return; 3269 } 3270 /* else, put it in the service queue */ 3271 if (!putq(wq, mp)) { 3272 freemsg(mp); 3273 } 3274 break; 3275 case M_FLUSH: 3276 if (*mp->b_rptr & FLUSHW) { 3277 flushq(wq, FLUSHDATA); 3278 } 3279 putnext(wq, mp); 3280 break; 3281 case M_IOCTL: 3282 iocp = (struct iocblk *)mp->b_rptr; 3283 switch (iocp->ioc_cmd) { 3284 case CRYPTIOCSETUP: 3285 ret = 0; 3286 (void) (STRLOG(CRYPTMOD_ID, 0, 5, 3287 SL_TRACE | SL_NOTE, 3288 "wput: got CRYPTIOCSETUP " 3289 "ioctl(%d)", iocp->ioc_cmd)); 3290 3291 if ((err = miocpullup(mp, 3292 sizeof (struct cr_info_t))) != 0) { 3293 cmn_err(CE_WARN, 3294 "wput: miocpullup failed for cr_info_t"); 3295 miocnak(wq, mp, 0, err); 3296 } else { 3297 struct cr_info_t *ci; 3298 ci = (struct cr_info_t *)mp->b_cont->b_rptr; 3299 3300 if (ci->direction_mask & CRYPT_ENCRYPT) { 3301 ret = setup_crypto(ci, &tmi->enc_data, 1); 3302 } 3303 3304 if (ret == 0 && 3305 (ci->direction_mask & CRYPT_DECRYPT)) { 3306 ret = setup_crypto(ci, &tmi->dec_data, 0); 3307 } 3308 if (ret == 0 && 3309 (ci->direction_mask & CRYPT_DECRYPT) && 3310 ANY_RCMD_MODE(tmi->dec_data.option_mask)) { 3311 bzero(&tmi->rcmd_state, 3312 sizeof (tmi->rcmd_state)); 3313 } 3314 if (ret == 0) { 3315 miocack(wq, mp, 0, 0); 3316 } else { 3317 cmn_err(CE_WARN, 3318 "wput: setup_crypto failed"); 3319 miocnak(wq, mp, 0, ret); 3320 } 3321 (void) (STRLOG(CRYPTMOD_ID, 0, 5, 3322 SL_TRACE|SL_NOTE, 3323 "wput: done with SETUP " 3324 "ioctl")); 3325 } 3326 break; 3327 case CRYPTIOCSTOP: 3328 (void) (STRLOG(CRYPTMOD_ID, 0, 5, 3329 SL_TRACE|SL_NOTE, 3330 "wput: got CRYPTIOCSTOP " 3331 "ioctl(%d)", iocp->ioc_cmd)); 3332 3333 if ((err = miocpullup(mp, sizeof (uint32_t))) != 0) { 3334 cmn_err(CE_WARN, 3335 "wput: CRYPTIOCSTOP ioctl wrong " 3336 "size (%d should be %d)", 3337 (int)iocp->ioc_count, 3338 (int)sizeof (uint32_t)); 3339 miocnak(wq, mp, 0, err); 3340 } else { 3341 uint32_t *stopdir; 3342 3343 stopdir = (uint32_t *)mp->b_cont->b_rptr; 3344 if (!CR_DIRECTION_OK(*stopdir)) { 3345 miocnak(wq, mp, 0, EINVAL); 3346 return; 3347 } 3348 3349 /* disable the queues until further notice */ 3350 if (*stopdir & CRYPT_ENCRYPT) { 3351 noenable(wq); 3352 tmi->ready &= ~CRYPT_WRITE_READY; 3353 } 3354 if (*stopdir & CRYPT_DECRYPT) { 3355 noenable(RD(wq)); 3356 tmi->ready &= ~CRYPT_READ_READY; 3357 } 3358 3359 miocack(wq, mp, 0, 0); 3360 } 3361 break; 3362 case CRYPTIOCSTARTDEC: 3363 (void) (STRLOG(CRYPTMOD_ID, 0, 5, 3364 SL_TRACE|SL_NOTE, 3365 "wput: got CRYPTIOCSTARTDEC " 3366 "ioctl(%d)", iocp->ioc_cmd)); 3367 3368 start_stream(wq, mp, CRYPT_DECRYPT); 3369 break; 3370 case CRYPTIOCSTARTENC: 3371 (void) (STRLOG(CRYPTMOD_ID, 0, 5, 3372 SL_TRACE|SL_NOTE, 3373 "wput: got CRYPTIOCSTARTENC " 3374 "ioctl(%d)", iocp->ioc_cmd)); 3375 3376 start_stream(wq, mp, CRYPT_ENCRYPT); 3377 break; 3378 default: 3379 putnext(wq, mp); 3380 break; 3381 } 3382 break; 3383 default: 3384 if (queclass(mp) < QPCTL) { 3385 if (wq->q_first != NULL || !canputnext(wq)) { 3386 if (!putq(wq, mp)) 3387 freemsg(mp); 3388 return; 3389 } 3390 } 3391 putnext(wq, mp); 3392 break; 3393 } 3394 } 3395 3396 /* 3397 * decrypt_rcmd_mblks 3398 * 3399 * Because kerberized r* commands(rsh, rlogin, etc) 3400 * use a 4 byte length field to indicate the # of 3401 * PLAINTEXT bytes that are encrypted in the field 3402 * that follows, we must parse out each message and 3403 * break out the length fields prior to sending them 3404 * upstream to our Solaris r* clients/servers which do 3405 * NOT understand this format. 3406 * 3407 * Kerberized/encrypted message format: 3408 * ------------------------------- 3409 * | XXXX | N bytes of ciphertext| 3410 * ------------------------------- 3411 * 3412 * Where: XXXX = number of plaintext bytes that were encrypted in 3413 * to make the ciphertext field. This is done 3414 * because we are using a cipher that pads out to 3415 * an 8 byte boundary. We only want the application 3416 * layer to see the correct number of plain text bytes, 3417 * not plaintext + pad. So, after we decrypt, we 3418 * must trim the output block down to the intended 3419 * plaintext length and eliminate the pad bytes. 3420 * 3421 * This routine takes the entire input message, breaks it into 3422 * a new message that does not contain these length fields and 3423 * returns a message consisting of mblks filled with just ciphertext. 3424 * 3425 */ 3426 static mblk_t * 3427 decrypt_rcmd_mblks(queue_t *q, mblk_t *mp) 3428 { 3429 mblk_t *newmp = NULL; 3430 size_t msglen; 3431 struct tmodinfo *tmi = (struct tmodinfo *)q->q_ptr; 3432 3433 msglen = msgsize(mp); 3434 3435 /* 3436 * If we need the length field, get it here. 3437 * Test the "plaintext length" indicator. 3438 */ 3439 if (tmi->rcmd_state.pt_len == 0) { 3440 uint32_t elen; 3441 int tocopy; 3442 mblk_t *nextp; 3443 3444 /* 3445 * Make sure we have recieved all 4 bytes of the 3446 * length field. 3447 */ 3448 while (mp != NULL) { 3449 ASSERT(tmi->rcmd_state.cd_len < sizeof (uint32_t)); 3450 3451 tocopy = sizeof (uint32_t) - 3452 tmi->rcmd_state.cd_len; 3453 if (tocopy > msglen) 3454 tocopy = msglen; 3455 3456 ASSERT(mp->b_rptr + tocopy <= DB_LIM(mp)); 3457 bcopy(mp->b_rptr, 3458 (char *)(&tmi->rcmd_state.next_len + 3459 tmi->rcmd_state.cd_len), tocopy); 3460 3461 tmi->rcmd_state.cd_len += tocopy; 3462 3463 if (tmi->rcmd_state.cd_len >= sizeof (uint32_t)) { 3464 tmi->rcmd_state.next_len = 3465 ntohl(tmi->rcmd_state.next_len); 3466 break; 3467 } 3468 3469 nextp = mp->b_cont; 3470 mp->b_cont = NULL; 3471 freeb(mp); 3472 mp = nextp; 3473 } 3474 3475 if (mp == NULL) { 3476 return (NULL); 3477 } 3478 /* 3479 * recalculate the msglen now that we've read the 3480 * length and adjusted the bufptr (b_rptr). 3481 */ 3482 msglen -= tocopy; 3483 mp->b_rptr += tocopy; 3484 3485 tmi->rcmd_state.pt_len = tmi->rcmd_state.next_len; 3486 3487 if (tmi->rcmd_state.pt_len <= 0) { 3488 /* 3489 * Return an IO error to break the connection. there 3490 * is no way to recover from this. Usually it means 3491 * the app has incorrectly requested decryption on 3492 * a non-encrypted stream, thus the "pt_len" field 3493 * is negative. 3494 */ 3495 mp->b_datap->db_type = M_ERROR; 3496 mp->b_rptr = mp->b_datap->db_base; 3497 *mp->b_rptr = EIO; 3498 mp->b_wptr = mp->b_rptr + sizeof (char); 3499 3500 freemsg(mp->b_cont); 3501 mp->b_cont = NULL; 3502 qreply(WR(q), mp); 3503 tmi->rcmd_state.cd_len = tmi->rcmd_state.pt_len = 0; 3504 return (NULL); 3505 } 3506 3507 /* 3508 * If this is V2 mode, then the encrypted data is actually 3509 * 4 bytes bigger than the indicated len because the plaintext 3510 * length is encrypted for an additional security check, but 3511 * its not counted as part of the overall length we just read. 3512 * Strange and confusing, but true. 3513 */ 3514 3515 if (tmi->dec_data.option_mask & CRYPTOPT_RCMD_MODE_V2) 3516 elen = tmi->rcmd_state.pt_len + 4; 3517 else 3518 elen = tmi->rcmd_state.pt_len; 3519 3520 tmi->rcmd_state.cd_len = encrypt_size(&tmi->dec_data, elen); 3521 3522 /* 3523 * Allocate an mblk to hold the cipher text until it is 3524 * all ready to be processed. 3525 */ 3526 tmi->rcmd_state.c_msg = allocb(tmi->rcmd_state.cd_len, 3527 BPRI_HI); 3528 if (tmi->rcmd_state.c_msg == NULL) { 3529 #ifdef DEBUG 3530 cmn_err(CE_WARN, "decrypt_rcmd_msgb: allocb failed " 3531 "for %d bytes", 3532 (int)tmi->rcmd_state.cd_len); 3533 #endif 3534 /* 3535 * Return an IO error to break the connection. 3536 */ 3537 mp->b_datap->db_type = M_ERROR; 3538 mp->b_rptr = mp->b_datap->db_base; 3539 *mp->b_rptr = EIO; 3540 mp->b_wptr = mp->b_rptr + sizeof (char); 3541 freemsg(mp->b_cont); 3542 mp->b_cont = NULL; 3543 tmi->rcmd_state.cd_len = tmi->rcmd_state.pt_len = 0; 3544 qreply(WR(q), mp); 3545 return (NULL); 3546 } 3547 } 3548 3549 /* 3550 * If this entire message was just the length field, 3551 * free and return. The actual data will probably be next. 3552 */ 3553 if (msglen == 0) { 3554 freemsg(mp); 3555 return (NULL); 3556 } 3557 3558 /* 3559 * Copy as much of the cipher text as possible into 3560 * the new msgb (c_msg). 3561 * 3562 * Logic: if we got some bytes (msglen) and we still 3563 * "need" some bytes (len-rcvd), get them here. 3564 */ 3565 ASSERT(tmi->rcmd_state.c_msg != NULL); 3566 if (msglen > 0 && 3567 (tmi->rcmd_state.cd_len > MBLKL(tmi->rcmd_state.c_msg))) { 3568 mblk_t *bp, *nextp; 3569 size_t n; 3570 3571 /* 3572 * Walk the mblks and copy just as many bytes as we need 3573 * for this particular block of cipher text. 3574 */ 3575 bp = mp; 3576 while (bp != NULL) { 3577 size_t needed; 3578 size_t tocopy; 3579 n = MBLKL(bp); 3580 3581 needed = tmi->rcmd_state.cd_len - 3582 MBLKL(tmi->rcmd_state.c_msg); 3583 3584 tocopy = (needed >= n ? n : needed); 3585 3586 ASSERT(bp->b_rptr + tocopy <= DB_LIM(bp)); 3587 ASSERT(tmi->rcmd_state.c_msg->b_wptr + tocopy <= 3588 DB_LIM(tmi->rcmd_state.c_msg)); 3589 3590 /* Copy to end of new mblk */ 3591 bcopy(bp->b_rptr, tmi->rcmd_state.c_msg->b_wptr, 3592 tocopy); 3593 3594 tmi->rcmd_state.c_msg->b_wptr += tocopy; 3595 3596 bp->b_rptr += tocopy; 3597 3598 nextp = bp->b_cont; 3599 3600 /* 3601 * If we used this whole block, free it and 3602 * move on. 3603 */ 3604 if (!MBLKL(bp)) { 3605 freeb(bp); 3606 bp = NULL; 3607 } 3608 3609 /* If we got what we needed, stop the loop */ 3610 if (MBLKL(tmi->rcmd_state.c_msg) == 3611 tmi->rcmd_state.cd_len) { 3612 /* 3613 * If there is more data in the message, 3614 * its for another block of cipher text, 3615 * put it back in the queue for next time. 3616 */ 3617 if (bp) { 3618 if (!putbq(q, bp)) 3619 freemsg(bp); 3620 } else if (nextp != NULL) { 3621 /* 3622 * If there is more, put it back in the 3623 * queue for another pass thru. 3624 */ 3625 if (!putbq(q, nextp)) 3626 freemsg(nextp); 3627 } 3628 break; 3629 } 3630 bp = nextp; 3631 } 3632 } 3633 /* 3634 * Finally, if we received all the cipher text data for 3635 * this message, decrypt it into a new msg and send it up 3636 * to the app. 3637 */ 3638 if (tmi->rcmd_state.pt_len > 0 && 3639 MBLKL(tmi->rcmd_state.c_msg) == tmi->rcmd_state.cd_len) { 3640 mblk_t *bp; 3641 mblk_t *newbp; 3642 3643 /* 3644 * Now we can use our msg that we created when the 3645 * initial message boundary was detected. 3646 */ 3647 bp = tmi->rcmd_state.c_msg; 3648 tmi->rcmd_state.c_msg = NULL; 3649 3650 newbp = do_decrypt(q, bp); 3651 if (newbp != NULL) { 3652 bp = newbp; 3653 /* 3654 * If using RCMD_MODE_V2 ("new" mode), 3655 * look at the 4 byte plaintext length that 3656 * was just decrypted and compare with the 3657 * original pt_len value that was received. 3658 */ 3659 if (tmi->dec_data.option_mask & 3660 CRYPTOPT_RCMD_MODE_V2) { 3661 uint32_t pt_len2; 3662 3663 pt_len2 = *(uint32_t *)bp->b_rptr; 3664 pt_len2 = ntohl(pt_len2); 3665 /* 3666 * Make sure the 2 pt len fields agree. 3667 */ 3668 if (pt_len2 != tmi->rcmd_state.pt_len) { 3669 cmn_err(CE_WARN, 3670 "Inconsistent length fields" 3671 " received %d != %d", 3672 (int)tmi->rcmd_state.pt_len, 3673 (int)pt_len2); 3674 bp->b_datap->db_type = M_ERROR; 3675 bp->b_rptr = bp->b_datap->db_base; 3676 *bp->b_rptr = EIO; 3677 bp->b_wptr = bp->b_rptr + sizeof (char); 3678 freemsg(bp->b_cont); 3679 bp->b_cont = NULL; 3680 tmi->rcmd_state.cd_len = 0; 3681 qreply(WR(q), bp); 3682 return (NULL); 3683 } 3684 bp->b_rptr += sizeof (uint32_t); 3685 } 3686 3687 /* 3688 * Trim the decrypted block the length originally 3689 * indicated by the sender. This is to remove any 3690 * padding bytes that the sender added to satisfy 3691 * requirements of the crypto algorithm. 3692 */ 3693 bp->b_wptr = bp->b_rptr + tmi->rcmd_state.pt_len; 3694 3695 newmp = bp; 3696 3697 /* 3698 * Reset our state to indicate we are ready 3699 * for a new message. 3700 */ 3701 tmi->rcmd_state.pt_len = 0; 3702 tmi->rcmd_state.cd_len = 0; 3703 } else { 3704 #ifdef DEBUG 3705 cmn_err(CE_WARN, 3706 "decrypt_rcmd: do_decrypt on %d bytes failed", 3707 (int)tmi->rcmd_state.cd_len); 3708 #endif 3709 /* 3710 * do_decrypt already handled failures, just 3711 * return NULL. 3712 */ 3713 tmi->rcmd_state.pt_len = 0; 3714 tmi->rcmd_state.cd_len = 0; 3715 return (NULL); 3716 } 3717 } 3718 3719 /* 3720 * return the new message with the 'length' fields removed 3721 */ 3722 return (newmp); 3723 } 3724 3725 /* 3726 * cryptmodrsrv 3727 * 3728 * Read queue service routine 3729 * Necessary because if the ready flag is not set 3730 * (via CRYPTIOCSTOP/CRYPTIOCSTART ioctls) then the data 3731 * must remain on queue and not be passed along. 3732 */ 3733 static int 3734 cryptmodrsrv(queue_t *q) 3735 { 3736 mblk_t *mp, *bp; 3737 struct tmodinfo *tmi = (struct tmodinfo *)q->q_ptr; 3738 3739 while ((mp = getq(q)) != NULL) { 3740 switch (mp->b_datap->db_type) { 3741 case M_DATA: 3742 if (canputnext(q) && tmi->ready & CRYPT_READ_READY) { 3743 /* 3744 * Process "rcmd" messages differently because 3745 * they contain a 4 byte plaintext length 3746 * id that needs to be removed. 3747 */ 3748 if (tmi->dec_data.method != CRYPT_METHOD_NONE && 3749 (tmi->dec_data.option_mask & 3750 (CRYPTOPT_RCMD_MODE_V1 | 3751 CRYPTOPT_RCMD_MODE_V2))) { 3752 mp = decrypt_rcmd_mblks(q, mp); 3753 if (mp) 3754 putnext(q, mp); 3755 continue; 3756 } 3757 if ((bp = msgpullup(mp, -1)) != NULL) { 3758 freemsg(mp); 3759 if (MBLKL(bp) > 0) { 3760 mp = do_decrypt(q, bp); 3761 if (mp != NULL) 3762 putnext(q, mp); 3763 } 3764 } 3765 } else { 3766 if (!putbq(q, mp)) { 3767 freemsg(mp); 3768 } 3769 return (0); 3770 } 3771 break; 3772 default: 3773 /* 3774 * rput does not queue anything > QPCTL, so we don't 3775 * need to check for it here. 3776 */ 3777 if (!canputnext(q)) { 3778 if (!putbq(q, mp)) 3779 freemsg(mp); 3780 return (0); 3781 } 3782 putnext(q, mp); 3783 break; 3784 } 3785 } 3786 return (0); 3787 } 3788 3789 3790 /* 3791 * Read-side put procedure. 3792 */ 3793 static void 3794 cryptmodrput(queue_t *rq, mblk_t *mp) 3795 { 3796 switch (mp->b_datap->db_type) { 3797 case M_DATA: 3798 if (!putq(rq, mp)) { 3799 freemsg(mp); 3800 } 3801 break; 3802 case M_FLUSH: 3803 if (*mp->b_rptr & FLUSHR) { 3804 flushq(rq, FLUSHALL); 3805 } 3806 putnext(rq, mp); 3807 break; 3808 default: 3809 if (queclass(mp) < QPCTL) { 3810 if (rq->q_first != NULL || !canputnext(rq)) { 3811 if (!putq(rq, mp)) 3812 freemsg(mp); 3813 return; 3814 } 3815 } 3816 putnext(rq, mp); 3817 break; 3818 } 3819 } 3820