1 /* 2 * Copyright 2008 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 #pragma ident "%Z%%M% %I% %E% SMI" 41 42 #include <sys/types.h> 43 #include <sys/sysmacros.h> 44 #include <sys/errno.h> 45 #include <sys/debug.h> 46 #include <sys/time.h> 47 #include <sys/stropts.h> 48 #include <sys/stream.h> 49 #include <sys/strsubr.h> 50 #include <sys/strlog.h> 51 #include <sys/cmn_err.h> 52 #include <sys/conf.h> 53 #include <sys/sunddi.h> 54 #include <sys/kmem.h> 55 #include <sys/strsun.h> 56 #include <sys/random.h> 57 #include <sys/types.h> 58 #include <sys/byteorder.h> 59 #include <sys/cryptmod.h> 60 #include <sys/crc32.h> 61 #include <sys/policy.h> 62 63 #include <sys/crypto/api.h> 64 65 #include <sys/strft.h> 66 /* 67 * Function prototypes. 68 */ 69 static int cryptmodopen(queue_t *, dev_t *, int, int, cred_t *); 70 static void cryptmodrput(queue_t *, mblk_t *); 71 static void cryptmodwput(queue_t *, mblk_t *); 72 static int cryptmodclose(queue_t *); 73 static int cryptmodwsrv(queue_t *); 74 static int cryptmodrsrv(queue_t *); 75 76 static mblk_t *do_encrypt(queue_t *q, mblk_t *mp); 77 static mblk_t *do_decrypt(queue_t *q, mblk_t *mp); 78 79 #define CRYPTMOD_ID 5150 80 81 #define CFB_BLKSZ 8 82 83 #define K5CLENGTH 5 84 85 static struct module_info cryptmod_minfo = { 86 CRYPTMOD_ID, /* mi_idnum */ 87 "cryptmod", /* mi_idname */ 88 0, /* mi_minpsz */ 89 INFPSZ, /* mi_maxpsz */ 90 65536, /* mi_hiwat */ 91 1024 /* mi_lowat */ 92 }; 93 94 static struct qinit cryptmod_rinit = { 95 (int (*)())cryptmodrput, /* qi_putp */ 96 cryptmodrsrv, /* qi_svc */ 97 cryptmodopen, /* qi_qopen */ 98 cryptmodclose, /* qi_qclose */ 99 NULL, /* qi_qadmin */ 100 &cryptmod_minfo, /* qi_minfo */ 101 NULL /* qi_mstat */ 102 }; 103 104 static struct qinit cryptmod_winit = { 105 (int (*)())cryptmodwput, /* qi_putp */ 106 cryptmodwsrv, /* qi_srvp */ 107 NULL, /* qi_qopen */ 108 NULL, /* qi_qclose */ 109 NULL, /* qi_qadmin */ 110 &cryptmod_minfo, /* qi_minfo */ 111 NULL /* qi_mstat */ 112 }; 113 114 static struct streamtab cryptmod_info = { 115 &cryptmod_rinit, /* st_rdinit */ 116 &cryptmod_winit, /* st_wrinit */ 117 NULL, /* st_muxrinit */ 118 NULL /* st_muxwinit */ 119 }; 120 121 typedef struct { 122 uint_t hash_len; 123 uint_t confound_len; 124 int (*hashfunc)(); 125 } hash_info_t; 126 127 #define MAX_CKSUM_LEN 20 128 #define CONFOUNDER_LEN 8 129 130 #define SHA1_HASHSIZE 20 131 #define MD5_HASHSIZE 16 132 #define CRC32_HASHSIZE 4 133 #define MSGBUF_SIZE 4096 134 #define CONFOUNDER_BYTES 128 135 136 137 static int crc32_calc(uchar_t *, uchar_t *, uint_t); 138 static int md5_calc(uchar_t *, uchar_t *, uint_t); 139 static int sha1_calc(uchar_t *, uchar_t *, uint_t); 140 141 static hash_info_t null_hash = {0, 0, NULL}; 142 static hash_info_t crc32_hash = {CRC32_HASHSIZE, CONFOUNDER_LEN, crc32_calc}; 143 static hash_info_t md5_hash = {MD5_HASHSIZE, CONFOUNDER_LEN, md5_calc}; 144 static hash_info_t sha1_hash = {SHA1_HASHSIZE, CONFOUNDER_LEN, sha1_calc}; 145 146 static crypto_mech_type_t sha1_hmac_mech = CRYPTO_MECH_INVALID; 147 static crypto_mech_type_t md5_hmac_mech = CRYPTO_MECH_INVALID; 148 static crypto_mech_type_t sha1_hash_mech = CRYPTO_MECH_INVALID; 149 static crypto_mech_type_t md5_hash_mech = CRYPTO_MECH_INVALID; 150 151 static int kef_crypt(struct cipher_data_t *, void *, 152 crypto_data_format_t, size_t, int); 153 static mblk_t * 154 arcfour_hmac_md5_encrypt(queue_t *, struct tmodinfo *, 155 mblk_t *, hash_info_t *); 156 static mblk_t * 157 arcfour_hmac_md5_decrypt(queue_t *, struct tmodinfo *, 158 mblk_t *, hash_info_t *); 159 160 static int 161 do_hmac(crypto_mech_type_t, crypto_key_t *, char *, int, char *, int); 162 163 /* 164 * This is the loadable module wrapper. 165 */ 166 #include <sys/modctl.h> 167 168 static struct fmodsw fsw = { 169 "cryptmod", 170 &cryptmod_info, 171 D_MP | D_MTQPAIR 172 }; 173 174 /* 175 * Module linkage information for the kernel. 176 */ 177 static struct modlstrmod modlstrmod = { 178 &mod_strmodops, 179 "STREAMS encryption module", 180 &fsw 181 }; 182 183 static struct modlinkage modlinkage = { 184 MODREV_1, 185 &modlstrmod, 186 NULL 187 }; 188 189 int 190 _init(void) 191 { 192 return (mod_install(&modlinkage)); 193 } 194 195 int 196 _fini(void) 197 { 198 return (mod_remove(&modlinkage)); 199 } 200 201 int 202 _info(struct modinfo *modinfop) 203 { 204 return (mod_info(&modlinkage, modinfop)); 205 } 206 207 static void 208 cleanup(struct cipher_data_t *cd) 209 { 210 if (cd->key != NULL) { 211 bzero(cd->key, cd->keylen); 212 kmem_free(cd->key, cd->keylen); 213 cd->key = NULL; 214 } 215 216 if (cd->ckey != NULL) { 217 /* 218 * ckey is a crypto_key_t structure which references 219 * "cd->key" for its raw key data. Since that was already 220 * cleared out, we don't need another "bzero" here. 221 */ 222 kmem_free(cd->ckey, sizeof (crypto_key_t)); 223 cd->ckey = NULL; 224 } 225 226 if (cd->block != NULL) { 227 kmem_free(cd->block, cd->blocklen); 228 cd->block = NULL; 229 } 230 231 if (cd->saveblock != NULL) { 232 kmem_free(cd->saveblock, cd->blocklen); 233 cd->saveblock = NULL; 234 } 235 236 if (cd->ivec != NULL) { 237 kmem_free(cd->ivec, cd->ivlen); 238 cd->ivec = NULL; 239 } 240 241 if (cd->d_encr_key.ck_data != NULL) { 242 bzero(cd->d_encr_key.ck_data, cd->keylen); 243 kmem_free(cd->d_encr_key.ck_data, cd->keylen); 244 } 245 246 if (cd->d_hmac_key.ck_data != NULL) { 247 bzero(cd->d_hmac_key.ck_data, cd->keylen); 248 kmem_free(cd->d_hmac_key.ck_data, cd->keylen); 249 } 250 251 if (cd->enc_tmpl != NULL) 252 (void) crypto_destroy_ctx_template(cd->enc_tmpl); 253 254 if (cd->hmac_tmpl != NULL) 255 (void) crypto_destroy_ctx_template(cd->hmac_tmpl); 256 257 if (cd->ctx != NULL) { 258 crypto_cancel_ctx(cd->ctx); 259 cd->ctx = NULL; 260 } 261 } 262 263 /* ARGSUSED */ 264 static int 265 cryptmodopen(queue_t *rq, dev_t *dev, int oflag, int sflag, cred_t *crp) 266 { 267 struct tmodinfo *tmi; 268 ASSERT(rq); 269 270 if (sflag != MODOPEN) 271 return (EINVAL); 272 273 (void) (STRLOG(CRYPTMOD_ID, 0, 5, SL_TRACE|SL_NOTE, 274 "cryptmodopen: opening module(PID %d)", 275 ddi_get_pid())); 276 277 if (rq->q_ptr != NULL) { 278 cmn_err(CE_WARN, "cryptmodopen: already opened"); 279 return (0); 280 } 281 282 /* 283 * Allocate and initialize per-Stream structure. 284 */ 285 tmi = (struct tmodinfo *)kmem_zalloc(sizeof (struct tmodinfo), 286 KM_SLEEP); 287 288 tmi->enc_data.method = CRYPT_METHOD_NONE; 289 tmi->dec_data.method = CRYPT_METHOD_NONE; 290 291 tmi->ready = (CRYPT_READ_READY | CRYPT_WRITE_READY); 292 293 rq->q_ptr = WR(rq)->q_ptr = tmi; 294 295 sha1_hmac_mech = crypto_mech2id(SUN_CKM_SHA1_HMAC); 296 md5_hmac_mech = crypto_mech2id(SUN_CKM_MD5_HMAC); 297 sha1_hash_mech = crypto_mech2id(SUN_CKM_SHA1); 298 md5_hash_mech = crypto_mech2id(SUN_CKM_MD5); 299 300 qprocson(rq); 301 302 return (0); 303 } 304 305 static int 306 cryptmodclose(queue_t *rq) 307 { 308 struct tmodinfo *tmi = (struct tmodinfo *)rq->q_ptr; 309 ASSERT(tmi); 310 311 qprocsoff(rq); 312 313 cleanup(&tmi->enc_data); 314 cleanup(&tmi->dec_data); 315 316 kmem_free(tmi, sizeof (struct tmodinfo)); 317 rq->q_ptr = WR(rq)->q_ptr = NULL; 318 319 return (0); 320 } 321 322 /* 323 * plaintext_offset 324 * 325 * Calculate exactly how much space is needed in front 326 * of the "plaintext" in an mbuf so it can be positioned 327 * 1 time instead of potentially moving the data multiple 328 * times. 329 */ 330 static int 331 plaintext_offset(struct cipher_data_t *cd) 332 { 333 int headspace = 0; 334 335 /* 4 byte length prepended to all RCMD msgs */ 336 if (ANY_RCMD_MODE(cd->option_mask)) 337 headspace += RCMD_LEN_SZ; 338 339 /* RCMD V2 mode adds an additional 4 byte plaintext length */ 340 if (cd->option_mask & CRYPTOPT_RCMD_MODE_V2) 341 headspace += RCMD_LEN_SZ; 342 343 /* Need extra space for hash and counfounder */ 344 switch (cd->method) { 345 case CRYPT_METHOD_DES_CBC_NULL: 346 headspace += null_hash.hash_len + null_hash.confound_len; 347 break; 348 case CRYPT_METHOD_DES_CBC_CRC: 349 headspace += crc32_hash.hash_len + crc32_hash.confound_len; 350 break; 351 case CRYPT_METHOD_DES_CBC_MD5: 352 headspace += md5_hash.hash_len + md5_hash.confound_len; 353 break; 354 case CRYPT_METHOD_DES3_CBC_SHA1: 355 headspace += sha1_hash.confound_len; 356 break; 357 case CRYPT_METHOD_ARCFOUR_HMAC_MD5: 358 headspace += md5_hash.hash_len + md5_hash.confound_len; 359 break; 360 case CRYPT_METHOD_AES128: 361 case CRYPT_METHOD_AES256: 362 headspace += DEFAULT_AES_BLOCKLEN; 363 break; 364 case CRYPT_METHOD_DES_CFB: 365 case CRYPT_METHOD_NONE: 366 break; 367 } 368 369 return (headspace); 370 } 371 /* 372 * encrypt_size 373 * 374 * Calculate the resulting size when encrypting 'plainlen' bytes 375 * of data. 376 */ 377 static size_t 378 encrypt_size(struct cipher_data_t *cd, size_t plainlen) 379 { 380 size_t cipherlen; 381 382 switch (cd->method) { 383 case CRYPT_METHOD_DES_CBC_NULL: 384 cipherlen = (size_t)P2ROUNDUP(null_hash.hash_len + 385 plainlen, 8); 386 break; 387 case CRYPT_METHOD_DES_CBC_MD5: 388 cipherlen = (size_t)P2ROUNDUP(md5_hash.hash_len + 389 md5_hash.confound_len + 390 plainlen, 8); 391 break; 392 case CRYPT_METHOD_DES_CBC_CRC: 393 cipherlen = (size_t)P2ROUNDUP(crc32_hash.hash_len + 394 crc32_hash.confound_len + 395 plainlen, 8); 396 break; 397 case CRYPT_METHOD_DES3_CBC_SHA1: 398 cipherlen = (size_t)P2ROUNDUP(sha1_hash.confound_len + 399 plainlen, 8) + 400 sha1_hash.hash_len; 401 break; 402 case CRYPT_METHOD_ARCFOUR_HMAC_MD5: 403 cipherlen = (size_t)P2ROUNDUP(md5_hash.confound_len + 404 plainlen, 1) + md5_hash.hash_len; 405 break; 406 case CRYPT_METHOD_AES128: 407 case CRYPT_METHOD_AES256: 408 /* No roundup for AES-CBC-CTS */ 409 cipherlen = DEFAULT_AES_BLOCKLEN + plainlen + 410 AES_TRUNCATED_HMAC_LEN; 411 break; 412 case CRYPT_METHOD_DES_CFB: 413 case CRYPT_METHOD_NONE: 414 cipherlen = plainlen; 415 break; 416 } 417 418 return (cipherlen); 419 } 420 421 /* 422 * des_cfb_encrypt 423 * 424 * Encrypt the mblk data using DES with cipher feedback. 425 * 426 * Given that V[i] is the initial 64 bit vector, V[n] is the nth 64 bit 427 * vector, D[n] is the nth chunk of 64 bits of data to encrypt 428 * (decrypt), and O[n] is the nth chunk of 64 bits of encrypted 429 * (decrypted) data, then: 430 * 431 * V[0] = DES(V[i], key) 432 * O[n] = D[n] <exclusive or > V[n] 433 * V[n+1] = DES(O[n], key) 434 * 435 * The size of the message being encrypted does not change in this 436 * algorithm, num_bytes in == num_bytes out. 437 */ 438 static mblk_t * 439 des_cfb_encrypt(queue_t *q, struct tmodinfo *tmi, mblk_t *mp) 440 { 441 int savedbytes; 442 char *iptr, *optr, *lastoutput; 443 444 lastoutput = optr = (char *)mp->b_rptr; 445 iptr = (char *)mp->b_rptr; 446 savedbytes = tmi->enc_data.bytes % CFB_BLKSZ; 447 448 while (iptr < (char *)mp->b_wptr) { 449 /* 450 * Do DES-ECB. 451 * The first time this runs, the 'tmi->enc_data.block' will 452 * contain the initialization vector that should have been 453 * passed in with the SETUP ioctl. 454 * 455 * V[n] = DES(V[n-1], key) 456 */ 457 if (!(tmi->enc_data.bytes % CFB_BLKSZ)) { 458 int retval = 0; 459 retval = kef_crypt(&tmi->enc_data, 460 tmi->enc_data.block, 461 CRYPTO_DATA_RAW, 462 tmi->enc_data.blocklen, 463 CRYPT_ENCRYPT); 464 465 if (retval != CRYPTO_SUCCESS) { 466 #ifdef DEBUG 467 cmn_err(CE_WARN, "des_cfb_encrypt: kef_crypt " 468 "failed - error 0x%0x", retval); 469 #endif 470 mp->b_datap->db_type = M_ERROR; 471 mp->b_rptr = mp->b_datap->db_base; 472 *mp->b_rptr = EIO; 473 mp->b_wptr = mp->b_rptr + sizeof (char); 474 freemsg(mp->b_cont); 475 mp->b_cont = NULL; 476 qreply(WR(q), mp); 477 return (NULL); 478 } 479 } 480 481 /* O[n] = I[n] ^ V[n] */ 482 *(optr++) = *(iptr++) ^ 483 tmi->enc_data.block[tmi->enc_data.bytes % CFB_BLKSZ]; 484 485 tmi->enc_data.bytes++; 486 /* 487 * Feedback the encrypted output as the input to next DES call. 488 */ 489 if (!(tmi->enc_data.bytes % CFB_BLKSZ)) { 490 char *dbptr = tmi->enc_data.block; 491 /* 492 * Get the last bits of input from the previous 493 * msg block that we haven't yet used as feedback input. 494 */ 495 if (savedbytes > 0) { 496 bcopy(tmi->enc_data.saveblock, 497 dbptr, (size_t)savedbytes); 498 dbptr += savedbytes; 499 } 500 501 /* 502 * Now copy the correct bytes from the current input 503 * stream and update the 'lastoutput' ptr 504 */ 505 bcopy(lastoutput, dbptr, 506 (size_t)(CFB_BLKSZ - savedbytes)); 507 508 lastoutput += (CFB_BLKSZ - savedbytes); 509 savedbytes = 0; 510 } 511 } 512 /* 513 * If there are bytes of input here that we need in the next 514 * block to build an ivec, save them off here. 515 */ 516 if (lastoutput < optr) { 517 bcopy(lastoutput, 518 tmi->enc_data.saveblock + savedbytes, 519 (uint_t)(optr - lastoutput)); 520 } 521 return (mp); 522 } 523 524 /* 525 * des_cfb_decrypt 526 * 527 * Decrypt the data in the mblk using DES in Cipher Feedback mode 528 * 529 * # bytes in == # bytes out, no padding, confounding, or hashing 530 * is added. 531 * 532 */ 533 static mblk_t * 534 des_cfb_decrypt(queue_t *q, struct tmodinfo *tmi, mblk_t *mp) 535 { 536 uint_t len; 537 uint_t savedbytes; 538 char *iptr; 539 char *lastinput; 540 uint_t cp; 541 542 len = MBLKL(mp); 543 544 /* decrypted output goes into the new data buffer */ 545 lastinput = iptr = (char *)mp->b_rptr; 546 547 savedbytes = tmi->dec_data.bytes % tmi->dec_data.blocklen; 548 549 /* 550 * Save the input CFB_BLKSZ bytes at a time. 551 * We are trying to decrypt in-place, but need to keep 552 * a small sliding window of encrypted text to be 553 * used to construct the feedback buffer. 554 */ 555 cp = ((tmi->dec_data.blocklen - savedbytes) > len ? len : 556 tmi->dec_data.blocklen - savedbytes); 557 558 bcopy(lastinput, tmi->dec_data.saveblock + savedbytes, cp); 559 savedbytes += cp; 560 561 lastinput += cp; 562 563 while (iptr < (char *)mp->b_wptr) { 564 /* 565 * Do DES-ECB. 566 * The first time this runs, the 'tmi->dec_data.block' will 567 * contain the initialization vector that should have been 568 * passed in with the SETUP ioctl. 569 */ 570 if (!(tmi->dec_data.bytes % CFB_BLKSZ)) { 571 int retval; 572 retval = kef_crypt(&tmi->dec_data, 573 tmi->dec_data.block, 574 CRYPTO_DATA_RAW, 575 tmi->dec_data.blocklen, 576 CRYPT_ENCRYPT); 577 578 if (retval != CRYPTO_SUCCESS) { 579 #ifdef DEBUG 580 cmn_err(CE_WARN, "des_cfb_decrypt: kef_crypt " 581 "failed - status 0x%0x", retval); 582 #endif 583 mp->b_datap->db_type = M_ERROR; 584 mp->b_rptr = mp->b_datap->db_base; 585 *mp->b_rptr = EIO; 586 mp->b_wptr = mp->b_rptr + sizeof (char); 587 freemsg(mp->b_cont); 588 mp->b_cont = NULL; 589 qreply(WR(q), mp); 590 return (NULL); 591 } 592 } 593 594 /* 595 * To decrypt, XOR the input with the output from the DES call 596 */ 597 *(iptr++) ^= tmi->dec_data.block[tmi->dec_data.bytes % 598 CFB_BLKSZ]; 599 600 tmi->dec_data.bytes++; 601 602 /* 603 * Feedback the encrypted input for next DES call. 604 */ 605 if (!(tmi->dec_data.bytes % tmi->dec_data.blocklen)) { 606 char *dbptr = tmi->dec_data.block; 607 /* 608 * Get the last bits of input from the previous block 609 * that we haven't yet processed. 610 */ 611 if (savedbytes > 0) { 612 bcopy(tmi->dec_data.saveblock, 613 dbptr, savedbytes); 614 dbptr += savedbytes; 615 } 616 617 savedbytes = 0; 618 619 /* 620 * This block makes sure that our local 621 * buffer of input data is full and can 622 * be accessed from the beginning. 623 */ 624 if (lastinput < (char *)mp->b_wptr) { 625 626 /* How many bytes are left in the mblk? */ 627 cp = (((char *)mp->b_wptr - lastinput) > 628 tmi->dec_data.blocklen ? 629 tmi->dec_data.blocklen : 630 (char *)mp->b_wptr - lastinput); 631 632 /* copy what we need */ 633 bcopy(lastinput, tmi->dec_data.saveblock, 634 cp); 635 636 lastinput += cp; 637 savedbytes = cp; 638 } 639 } 640 } 641 642 return (mp); 643 } 644 645 /* 646 * crc32_calc 647 * 648 * Compute a CRC32 checksum on the input 649 */ 650 static int 651 crc32_calc(uchar_t *buf, uchar_t *input, uint_t len) 652 { 653 uint32_t crc; 654 655 CRC32(crc, input, len, 0, crc32_table); 656 657 buf[0] = (uchar_t)(crc & 0xff); 658 buf[1] = (uchar_t)((crc >> 8) & 0xff); 659 buf[2] = (uchar_t)((crc >> 16) & 0xff); 660 buf[3] = (uchar_t)((crc >> 24) & 0xff); 661 662 return (CRYPTO_SUCCESS); 663 } 664 665 static int 666 kef_digest(crypto_mech_type_t digest_type, 667 uchar_t *input, uint_t inlen, 668 uchar_t *output, uint_t hashlen) 669 { 670 iovec_t v1, v2; 671 crypto_data_t d1, d2; 672 crypto_mechanism_t mech; 673 int rv; 674 675 mech.cm_type = digest_type; 676 mech.cm_param = 0; 677 mech.cm_param_len = 0; 678 679 v1.iov_base = (void *)input; 680 v1.iov_len = inlen; 681 682 d1.cd_format = CRYPTO_DATA_RAW; 683 d1.cd_offset = 0; 684 d1.cd_length = v1.iov_len; 685 d1.cd_raw = v1; 686 687 v2.iov_base = (void *)output; 688 v2.iov_len = hashlen; 689 690 d2.cd_format = CRYPTO_DATA_RAW; 691 d2.cd_offset = 0; 692 d2.cd_length = v2.iov_len; 693 d2.cd_raw = v2; 694 695 rv = crypto_digest(&mech, &d1, &d2, NULL); 696 697 return (rv); 698 } 699 700 /* 701 * sha1_calc 702 * 703 * Get a SHA1 hash on the input data. 704 */ 705 static int 706 sha1_calc(uchar_t *output, uchar_t *input, uint_t inlen) 707 { 708 int rv; 709 710 rv = kef_digest(sha1_hash_mech, input, inlen, output, SHA1_HASHSIZE); 711 712 return (rv); 713 } 714 715 /* 716 * Get an MD5 hash on the input data. 717 * md5_calc 718 * 719 */ 720 static int 721 md5_calc(uchar_t *output, uchar_t *input, uint_t inlen) 722 { 723 int rv; 724 725 rv = kef_digest(md5_hash_mech, input, inlen, output, MD5_HASHSIZE); 726 727 return (rv); 728 } 729 730 /* 731 * nfold 732 * duplicate the functionality of the krb5_nfold function from 733 * the userland kerberos mech. 734 * This is needed to derive keys for use with 3DES/SHA1-HMAC 735 * ciphers. 736 */ 737 static void 738 nfold(int inbits, uchar_t *in, int outbits, uchar_t *out) 739 { 740 int a, b, c, lcm; 741 int byte, i, msbit; 742 743 inbits >>= 3; 744 outbits >>= 3; 745 746 /* first compute lcm(n,k) */ 747 a = outbits; 748 b = inbits; 749 750 while (b != 0) { 751 c = b; 752 b = a%b; 753 a = c; 754 } 755 756 lcm = outbits*inbits/a; 757 758 /* now do the real work */ 759 760 bzero(out, outbits); 761 byte = 0; 762 763 /* 764 * Compute the msbit in k which gets added into this byte 765 * first, start with the msbit in the first, unrotated byte 766 * then, for each byte, shift to the right for each repetition 767 * last, pick out the correct byte within that shifted repetition 768 */ 769 for (i = lcm-1; i >= 0; i--) { 770 msbit = (((inbits<<3)-1) 771 +(((inbits<<3)+13)*(i/inbits)) 772 +((inbits-(i%inbits))<<3)) %(inbits<<3); 773 774 /* pull out the byte value itself */ 775 byte += (((in[((inbits-1)-(msbit>>3))%inbits]<<8)| 776 (in[((inbits)-(msbit>>3))%inbits])) 777 >>((msbit&7)+1))&0xff; 778 779 /* do the addition */ 780 byte += out[i%outbits]; 781 out[i%outbits] = byte&0xff; 782 783 byte >>= 8; 784 } 785 786 /* if there's a carry bit left over, add it back in */ 787 if (byte) { 788 for (i = outbits-1; i >= 0; i--) { 789 /* do the addition */ 790 byte += out[i]; 791 out[i] = byte&0xff; 792 793 /* keep around the carry bit, if any */ 794 byte >>= 8; 795 } 796 } 797 } 798 799 #define smask(step) ((1<<step)-1) 800 #define pstep(x, step) (((x)&smask(step))^(((x)>>step)&smask(step))) 801 #define parity_char(x) pstep(pstep(pstep((x), 4), 2), 1) 802 803 /* 804 * Duplicate the functionality of the "dk_derive_key" function 805 * in the Kerberos mechanism. 806 */ 807 static int 808 derive_key(struct cipher_data_t *cdata, uchar_t *constdata, 809 int constlen, char *dkey, int keybytes, 810 int blocklen) 811 { 812 int rv = 0; 813 int n = 0, i; 814 char *inblock; 815 char *rawkey; 816 char *zeroblock; 817 char *saveblock; 818 819 inblock = kmem_zalloc(blocklen, KM_SLEEP); 820 rawkey = kmem_zalloc(keybytes, KM_SLEEP); 821 zeroblock = kmem_zalloc(blocklen, KM_SLEEP); 822 823 if (constlen == blocklen) 824 bcopy(constdata, inblock, blocklen); 825 else 826 nfold(constlen * 8, constdata, 827 blocklen * 8, (uchar_t *)inblock); 828 829 /* 830 * zeroblock is an IV of all 0's. 831 * 832 * The "block" section of the cdata record is used as the 833 * IV for crypto operations in the kef_crypt function. 834 * 835 * We use 'block' as a generic IV data buffer because it 836 * is attached to the stream state data and thus can 837 * be used to hold information that must carry over 838 * from processing of one mblk to another. 839 * 840 * Here, we save the current IV and replace it with 841 * and empty IV (all 0's) for use when deriving the 842 * keys. Once the key derivation is done, we swap the 843 * old IV back into place. 844 */ 845 saveblock = cdata->block; 846 cdata->block = zeroblock; 847 848 while (n < keybytes) { 849 rv = kef_crypt(cdata, inblock, CRYPTO_DATA_RAW, 850 blocklen, CRYPT_ENCRYPT); 851 if (rv != CRYPTO_SUCCESS) { 852 /* put the original IV block back in place */ 853 cdata->block = saveblock; 854 cmn_err(CE_WARN, "failed to derive a key: %0x", rv); 855 goto cleanup; 856 } 857 858 if (keybytes - n < blocklen) { 859 bcopy(inblock, rawkey+n, (keybytes-n)); 860 break; 861 } 862 bcopy(inblock, rawkey+n, blocklen); 863 n += blocklen; 864 } 865 /* put the original IV block back in place */ 866 cdata->block = saveblock; 867 868 /* finally, make the key */ 869 if (cdata->method == CRYPT_METHOD_DES3_CBC_SHA1) { 870 /* 871 * 3DES key derivation requires that we make sure the 872 * key has the proper parity. 873 */ 874 for (i = 0; i < 3; i++) { 875 bcopy(rawkey+(i*7), dkey+(i*8), 7); 876 877 /* 'dkey' is our derived key output buffer */ 878 dkey[i*8+7] = (((dkey[i*8]&1)<<1) | 879 ((dkey[i*8+1]&1)<<2) | 880 ((dkey[i*8+2]&1)<<3) | 881 ((dkey[i*8+3]&1)<<4) | 882 ((dkey[i*8+4]&1)<<5) | 883 ((dkey[i*8+5]&1)<<6) | 884 ((dkey[i*8+6]&1)<<7)); 885 886 for (n = 0; n < 8; n++) { 887 dkey[i*8 + n] &= 0xfe; 888 dkey[i*8 + n] |= 1^parity_char(dkey[i*8 + n]); 889 } 890 } 891 } else if (IS_AES_METHOD(cdata->method)) { 892 bcopy(rawkey, dkey, keybytes); 893 } 894 cleanup: 895 kmem_free(inblock, blocklen); 896 kmem_free(zeroblock, blocklen); 897 kmem_free(rawkey, keybytes); 898 return (rv); 899 } 900 901 /* 902 * create_derived_keys 903 * 904 * Algorithm for deriving a new key and an HMAC key 905 * before computing the 3DES-SHA1-HMAC operation on the plaintext 906 * This algorithm matches the work done by Kerberos mechanism 907 * in userland. 908 */ 909 static int 910 create_derived_keys(struct cipher_data_t *cdata, uint32_t usage, 911 crypto_key_t *enckey, crypto_key_t *hmackey) 912 { 913 uchar_t constdata[K5CLENGTH]; 914 int keybytes; 915 int rv; 916 917 constdata[0] = (usage>>24)&0xff; 918 constdata[1] = (usage>>16)&0xff; 919 constdata[2] = (usage>>8)&0xff; 920 constdata[3] = usage & 0xff; 921 /* Use "0xAA" for deriving encryption key */ 922 constdata[4] = 0xAA; /* from MIT Kerberos code */ 923 924 enckey->ck_length = cdata->keylen * 8; 925 enckey->ck_format = CRYPTO_KEY_RAW; 926 enckey->ck_data = kmem_zalloc(cdata->keylen, KM_SLEEP); 927 928 switch (cdata->method) { 929 case CRYPT_METHOD_DES_CFB: 930 case CRYPT_METHOD_DES_CBC_NULL: 931 case CRYPT_METHOD_DES_CBC_MD5: 932 case CRYPT_METHOD_DES_CBC_CRC: 933 keybytes = 8; 934 break; 935 case CRYPT_METHOD_DES3_CBC_SHA1: 936 keybytes = CRYPT_DES3_KEYBYTES; 937 break; 938 case CRYPT_METHOD_ARCFOUR_HMAC_MD5: 939 case CRYPT_METHOD_ARCFOUR_HMAC_MD5_EXP: 940 keybytes = CRYPT_ARCFOUR_KEYBYTES; 941 break; 942 case CRYPT_METHOD_AES128: 943 keybytes = CRYPT_AES128_KEYBYTES; 944 break; 945 case CRYPT_METHOD_AES256: 946 keybytes = CRYPT_AES256_KEYBYTES; 947 break; 948 } 949 950 /* derive main crypto key */ 951 rv = derive_key(cdata, constdata, sizeof (constdata), 952 enckey->ck_data, keybytes, cdata->blocklen); 953 954 if (rv == CRYPTO_SUCCESS) { 955 956 /* Use "0x55" for deriving mac key */ 957 constdata[4] = 0x55; 958 959 hmackey->ck_length = cdata->keylen * 8; 960 hmackey->ck_format = CRYPTO_KEY_RAW; 961 hmackey->ck_data = kmem_zalloc(cdata->keylen, KM_SLEEP); 962 963 rv = derive_key(cdata, constdata, sizeof (constdata), 964 hmackey->ck_data, keybytes, 965 cdata->blocklen); 966 } else { 967 cmn_err(CE_WARN, "failed to derive crypto key: %02x", rv); 968 } 969 970 return (rv); 971 } 972 973 /* 974 * Compute 3-DES crypto and HMAC. 975 */ 976 static int 977 kef_decr_hmac(struct cipher_data_t *cdata, 978 mblk_t *mp, int length, 979 char *hmac, int hmaclen) 980 { 981 int rv = CRYPTO_FAILED; 982 983 crypto_mechanism_t encr_mech; 984 crypto_mechanism_t mac_mech; 985 crypto_data_t dd; 986 crypto_data_t mac; 987 iovec_t v1; 988 989 ASSERT(cdata != NULL); 990 ASSERT(mp != NULL); 991 ASSERT(hmac != NULL); 992 993 bzero(&dd, sizeof (dd)); 994 dd.cd_format = CRYPTO_DATA_MBLK; 995 dd.cd_offset = 0; 996 dd.cd_length = length; 997 dd.cd_mp = mp; 998 999 v1.iov_base = hmac; 1000 v1.iov_len = hmaclen; 1001 1002 mac.cd_format = CRYPTO_DATA_RAW; 1003 mac.cd_offset = 0; 1004 mac.cd_length = hmaclen; 1005 mac.cd_raw = v1; 1006 1007 /* 1008 * cdata->block holds the IVEC 1009 */ 1010 encr_mech.cm_type = cdata->mech_type; 1011 encr_mech.cm_param = cdata->block; 1012 1013 if (cdata->block != NULL) 1014 encr_mech.cm_param_len = cdata->blocklen; 1015 else 1016 encr_mech.cm_param_len = 0; 1017 1018 rv = crypto_decrypt(&encr_mech, &dd, &cdata->d_encr_key, 1019 cdata->enc_tmpl, NULL, NULL); 1020 if (rv != CRYPTO_SUCCESS) { 1021 cmn_err(CE_WARN, "crypto_decrypt failed: %0x", rv); 1022 return (rv); 1023 } 1024 1025 mac_mech.cm_type = sha1_hmac_mech; 1026 mac_mech.cm_param = NULL; 1027 mac_mech.cm_param_len = 0; 1028 1029 /* 1030 * Compute MAC of the plaintext decrypted above. 1031 */ 1032 rv = crypto_mac(&mac_mech, &dd, &cdata->d_hmac_key, 1033 cdata->hmac_tmpl, &mac, NULL); 1034 1035 if (rv != CRYPTO_SUCCESS) { 1036 cmn_err(CE_WARN, "crypto_mac failed: %0x", rv); 1037 } 1038 1039 return (rv); 1040 } 1041 1042 /* 1043 * Compute 3-DES crypto and HMAC. 1044 */ 1045 static int 1046 kef_encr_hmac(struct cipher_data_t *cdata, 1047 mblk_t *mp, int length, 1048 char *hmac, int hmaclen) 1049 { 1050 int rv = CRYPTO_FAILED; 1051 1052 crypto_mechanism_t encr_mech; 1053 crypto_mechanism_t mac_mech; 1054 crypto_data_t dd; 1055 crypto_data_t mac; 1056 iovec_t v1; 1057 1058 ASSERT(cdata != NULL); 1059 ASSERT(mp != NULL); 1060 ASSERT(hmac != NULL); 1061 1062 bzero(&dd, sizeof (dd)); 1063 dd.cd_format = CRYPTO_DATA_MBLK; 1064 dd.cd_offset = 0; 1065 dd.cd_length = length; 1066 dd.cd_mp = mp; 1067 1068 v1.iov_base = hmac; 1069 v1.iov_len = hmaclen; 1070 1071 mac.cd_format = CRYPTO_DATA_RAW; 1072 mac.cd_offset = 0; 1073 mac.cd_length = hmaclen; 1074 mac.cd_raw = v1; 1075 1076 /* 1077 * cdata->block holds the IVEC 1078 */ 1079 encr_mech.cm_type = cdata->mech_type; 1080 encr_mech.cm_param = cdata->block; 1081 1082 if (cdata->block != NULL) 1083 encr_mech.cm_param_len = cdata->blocklen; 1084 else 1085 encr_mech.cm_param_len = 0; 1086 1087 mac_mech.cm_type = sha1_hmac_mech; 1088 mac_mech.cm_param = NULL; 1089 mac_mech.cm_param_len = 0; 1090 1091 rv = crypto_mac(&mac_mech, &dd, &cdata->d_hmac_key, 1092 cdata->hmac_tmpl, &mac, NULL); 1093 1094 if (rv !=