1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23 /* 24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 29 /* All Rights Reserved */ 30 31 /* 32 * Portions of this source code were derived from Berkeley 4.3 BSD 33 * under license from the Regents of the University of California. 34 */ 35 36 #pragma ident "%Z%%M% %I% %E% SMI" 37 38 /* 39 * Hex encryption/decryption and utility routines 40 */ 41 42 #include "mt.h" 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <sys/types.h> 46 #include <rpc/rpc.h> 47 #include <rpc/key_prot.h> /* for KEYCHECKSUMSIZE */ 48 #include <rpc/des_crypt.h> 49 #include <string.h> 50 #include <rpcsvc/nis_dhext.h> 51 #include <md5.h> 52 53 #define MD5HEXSIZE 32 54 55 extern int bin2hex(int len, unsigned char *binnum, char *hexnum); 56 extern int hex2bin(int len, char *hexnum, char *binnum); 57 static char hex[]; /* forward */ 58 static char hexval(); 59 60 int passwd2des(char *, char *); 61 static int weak_DES_key(des_block); 62 63 /* EXPORT DELETE START */ 64 /* 65 * For export control reasons, we want to limit the maximum size of 66 * data that can be encrypted or decrypted. We limit this to 1024 67 * bits of key data, which amounts to 128 bytes. 68 * 69 * For the extended DH project, we have increased it to 70 * 144 bytes (128key + 16checksum) to accomadate all the 128 bytes 71 * being used by the new 1024bit keys plus 16 bytes MD5 checksum. 72 * We discussed this with Sun's export control office and lawyers 73 * and we have reason to believe this is ok for export. 74 */ 75 #define MAX_KEY_CRYPT_LEN 144 76 /* EXPORT DELETE END */ 77 78 /* 79 * Encrypt a secret key given passwd 80 * The secret key is passed and returned in hex notation. 81 * Its length must be a multiple of 16 hex digits (64 bits). 82 */ 83 int 84 xencrypt(secret, passwd) 85 char *secret; 86 char *passwd; 87 { 88 /* EXPORT DELETE START */ 89 char key[8]; 90 char ivec[8]; 91 char *buf; 92 int err; 93 int len; 94 95 len = (int)strlen(secret) / 2; 96 if (len > MAX_KEY_CRYPT_LEN) 97 return (0); 98 buf = malloc((unsigned)len); 99 (void) hex2bin(len, secret, buf); 100 (void) passwd2des(passwd, key); 101 (void) memset(ivec, 0, 8); 102 103 err = cbc_crypt(key, buf, len, DES_ENCRYPT | DES_HW, ivec); 104 if (DES_FAILED(err)) { 105 free(buf); 106 return (0); 107 } 108 (void) bin2hex(len, (unsigned char *) buf, secret); 109 free(buf); 110 return (1); 111 #if 0 112 /* EXPORT DELETE END */ 113 return (0); 114 /* EXPORT DELETE START */ 115 #endif 116 /* EXPORT DELETE END */ 117 } 118 119 /* 120 * Decrypt secret key using passwd 121 * The secret key is passed and returned in hex notation. 122 * Once again, the length is a multiple of 16 hex digits 123 */ 124 int 125 xdecrypt(secret, passwd) 126 char *secret; 127 char *passwd; 128 { 129 /* EXPORT DELETE START */ 130 char key[8]; 131 char ivec[8]; 132 char *buf; 133 int err; 134 int len; 135 136 len = (int)strlen(secret) / 2; 137 if (len > MAX_KEY_CRYPT_LEN) 138 return (0); 139 buf = malloc((unsigned)len); 140 141 (void) hex2bin(len, secret, buf); 142 (void) passwd2des(passwd, key); 143 (void) memset(ivec, 0, 8); 144 145 err = cbc_crypt(key, buf, len, DES_DECRYPT | DES_HW, ivec); 146 if (DES_FAILED(err)) { 147 free(buf); 148 return (0); 149 } 150 (void) bin2hex(len, (unsigned char *) buf, secret); 151 free(buf); 152 return (1); 153 #if 0 154 /* EXPORT DELETE END */ 155 return (0); 156 /* EXPORT DELETE START */ 157 #endif 158 /* EXPORT DELETE END */ 159 } 160 161 /* 162 * Turn password into DES key 163 */ 164 int 165 passwd2des(pw, key) 166 char *pw; 167 char *key; 168 { 169 int i; 170 171 (void) memset(key, 0, 8); 172 for (i = 0; *pw; i = (i+1) % 8) { 173 key[i] ^= *pw++ << 1; 174 } 175 des_setparity(key); 176 return (1); 177 } 178 179 180 /* 181 * Hex to binary conversion 182 */ 183 int 184 hex2bin(len, hexnum, binnum) 185 int len; 186 char *hexnum; 187 char *binnum; 188 { 189 int i; 190 191 for (i = 0; i < len; i++) { 192 *binnum++ = 16 * hexval(hexnum[2 * i]) + 193 hexval(hexnum[2 * i + 1]); 194 } 195 return (1); 196 } 197 198 /* 199 * Binary to hex conversion 200 */ 201 int 202 bin2hex(len, binnum, hexnum) 203 int len; 204 unsigned char *binnum; 205 char *hexnum; 206 { 207 int i; 208 unsigned val; 209 210 for (i = 0; i < len; i++) { 211 val = binnum[i]; 212 hexnum[i*2] = hex[val >> 4]; 213 hexnum[i*2+1] = hex[val & 0xf]; 214 } 215 hexnum[len*2] = 0; 216 return (1); 217 } 218 219 static char hex[16] = { 220 '0', '1', '2', '3', '4', '5', '6', '7', 221 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 222 }; 223 224 static char 225 hexval(c) 226 char c; 227 { 228 if (c >= '0' && c <= '9') { 229 return (c - '0'); 230 } else if (c >= 'a' && c <= 'z') { 231 return (c - 'a' + 10); 232 } else if (c >= 'A' && c <= 'Z') { 233 return (c - 'A' + 10); 234 } else { 235 return (-1); 236 } 237 } 238 239 /* 240 * Generic key length/algorithm version of xencrypt(). 241 * 242 * Encrypt a secret key given passwd. 243 * The secret key is passed in hex notation. 244 * Arg encrypted_secret will be set to point to the encrypted 245 * secret key (NUL term, hex notation). 246 * 247 * Its length must be a multiple of 16 hex digits (64 bits). 248 * 249 * For 192-0 (AUTH_DES), then encrypt using the same method as xencrypt(). 250 * 251 * If arg do_chksum is TRUE, append the checksum before the encrypt. 252 * For 192-0, the checksum is done the same as in xencrypt(). For 253 * bigger keys, MD5 is used. 254 * 255 * Arg netname can be NULL for 192-0. 256 */ 257 int 258 xencrypt_g( 259 char *secret, /* in */ 260 keylen_t keylen, /* in */ 261 algtype_t algtype, /* in */ 262 const char *passwd, /* in */ 263 const char netname[], /* in */ 264 char **encrypted_secret, /* out */ 265 bool_t do_chksum) /* in */ 266 { 267 /* EXPORT DELETE START */ 268 des_block key; 269 char ivec[8]; 270 char *binkeybuf; 271 int err; 272 const int classic_des = keylen == 192 && algtype == 0; 273 const int hexkeybytes = BITS2NIBBLES(keylen); 274 const int keychecksumsize = classic_des ? KEYCHECKSUMSIZE : MD5HEXSIZE; 275 const int binkeybytes = do_chksum ? keylen/8 + keychecksumsize/2 : 276 keylen/8; 277 const int bufsize = do_chksum ? hexkeybytes + keychecksumsize + 1 : 278 hexkeybytes + 1; 279 char *hexkeybuf; 280 281 if (!secret || !keylen || !passwd || !encrypted_secret) 282 return (0); 283 284 if ((hexkeybuf = malloc(bufsize)) == 0) 285 return (0); 286 287 (void) memcpy(hexkeybuf, secret, hexkeybytes); 288 if (do_chksum) 289 if (classic_des) { 290 (void) memcpy(hexkeybuf + hexkeybytes, secret, 291 keychecksumsize); 292 } else { 293 MD5_CTX md5_ctx; 294 char md5hexbuf[MD5HEXSIZE + 1] = {0}; 295 uint8_t digest[MD5HEXSIZE/2]; 296 297 MD5Init(&md5_ctx); 298 MD5Update(&md5_ctx, (unsigned char *)hexkeybuf, 299 hexkeybytes); 300 MD5Final(digest, &md5_ctx); 301 302 /* convert md5 binary digest to hex */ 303 (void) bin2hex(MD5HEXSIZE/2, digest, md5hexbuf); 304 305 /* append the hex md5 string to the end of the key */ 306 (void) memcpy(hexkeybuf + hexkeybytes, 307 (void *)md5hexbuf, MD5HEXSIZE); 308 } 309 hexkeybuf[bufsize - 1] = 0; 310 311 if (binkeybytes > MAX_KEY_CRYPT_LEN) { 312 free(hexkeybuf); 313 return (0); 314 } 315 if ((binkeybuf = malloc((unsigned)binkeybytes)) == 0) { 316 free(hexkeybuf); 317 return (0); 318 } 319 320 (void) hex2bin(binkeybytes, hexkeybuf, binkeybuf); 321 if (classic_des) 322 (void) passwd2des((char *)passwd, key.c); 323 else 324 if (netname) 325 (void) passwd2des_g(passwd, netname, 326 (int)strlen(netname), &key, FALSE); 327 else { 328 free(hexkeybuf); 329 return (0); 330 } 331 332 (void) memset(ivec, 0, 8); 333 334 err = cbc_crypt(key.c, binkeybuf, binkeybytes, DES_ENCRYPT | DES_HW, 335 ivec); 336 if (DES_FAILED(err)) { 337 free(hexkeybuf); 338 free(binkeybuf); 339 return (0); 340 } 341 (void) bin2hex(binkeybytes, (unsigned char *) binkeybuf, hexkeybuf); 342 free(binkeybuf); 343 *encrypted_secret = hexkeybuf; 344 return (1); 345 #if 0 346 /* EXPORT DELETE END */ 347 return (0); 348 /* EXPORT DELETE START */ 349 #endif 350 /* EXPORT DELETE END */ 351 } 352 353 /* 354 * Generic key len and alg type for version of xdecrypt. 355 * 356 * Decrypt secret key using passwd. The decrypted secret key 357 * *overwrites* the supplied encrypted secret key. 358 * The secret key is passed and returned in hex notation. 359 * Once again, the length is a multiple of 16 hex digits. 360 * 361 * If 'do_chksum' is TRUE, the 'secret' buffer is assumed to contain 362 * a checksum calculated by a call to xencrypt_g(). 363 * 364 * If keylen is 192 and algtype is 0, then decrypt the same way 365 * as xdecrypt(). 366 * 367 * Arg netname can be NULL for 192-0. 368 */ 369 int 370 xdecrypt_g( 371 char *secret, /* out */ 372 int keylen, /* in */ 373 int algtype, /* in */ 374 const char *passwd, /* in */ 375 const char netname[], /* in */ 376 bool_t do_chksum) /* in */ 377 { 378 /* EXPORT DELETE START */ 379 des_block key; 380 char ivec[8]; 381 char *buf; 382 int err; 383 int len; 384 const int classic_des = keylen == 192 && algtype == 0; 385 const int hexkeybytes = BITS2NIBBLES(keylen); 386 const int keychecksumsize = classic_des ? KEYCHECKSUMSIZE : MD5HEXSIZE; 387 388 len = (int)strlen(secret) / 2; 389 if (len > MAX_KEY_CRYPT_LEN) 390 return (0); 391 if ((buf = malloc((unsigned)len)) == 0) 392 return (0); 393 394 (void) hex2bin(len, secret, buf); 395 if (classic_des) 396 (void) passwd2des((char *)passwd, key.c); 397 else 398 if (netname) 399 (void) passwd2des_g(passwd, netname, 400 (int)strlen(netname), &key, FALSE); 401 else { 402 free(buf); 403 return (0); 404 } 405 (void) memset(ivec, 0, 8); 406 407 err = cbc_crypt(key.c, buf, len, DES_DECRYPT | DES_HW, ivec); 408 if (DES_FAILED(err)) { 409 free(buf); 410 return (0); 411 } 412 (void) bin2hex(len, (unsigned char *) buf, secret); 413 free(buf); 414 415 if (do_chksum) 416 if (classic_des) { 417 if (memcmp(secret, &(secret[hexkeybytes]), 418 keychecksumsize) != 0) { 419 secret[0] = 0; 420 return (0); 421 } 422 } else { 423 MD5_CTX md5_ctx; 424 char md5hexbuf[MD5HEXSIZE + 1] = {0}; 425 uint8_t digest[MD5HEXSIZE/2]; 426 427 MD5Init(&md5_ctx); 428 MD5Update(&md5_ctx, (unsigned char *)secret, 429 hexkeybytes); 430 MD5Final(digest, &md5_ctx); 431 432 /* convert md5 binary digest to hex */ 433 (void) bin2hex(MD5HEXSIZE/2, digest, md5hexbuf); 434 435 /* does the digest match the appended one? */ 436 if (memcmp(&(secret[hexkeybytes]), 437 md5hexbuf, MD5HEXSIZE) != 0) { 438 secret[0] = 0; 439 return (0); 440 } 441 } 442 443 secret[hexkeybytes] = '\0'; 444 445 return (1); 446 #if 0 447 /* EXPORT DELETE END */ 448 return (0); 449 /* EXPORT DELETE START */ 450 #endif 451 /* EXPORT DELETE END */ 452 } 453 454 455 /* 456 * Modified version of passwd2des(). passwd2des_g() uses the Kerberos 457 * RFC 1510 algorithm to generate a DES key from a user password 458 * and mix-in string. The mix-in is expected to be the netname. 459 * This function to be used only for extended Diffie-Hellman keys. 460 * 461 * If altarg is TRUE, reverse the concat of passwd and mix-in. 462 */ 463 int 464 passwd2des_g( 465 const char *pw, 466 const char *mixin, 467 int len, 468 des_block *key, /* out */ 469 bool_t altalg) 470 { 471 472 int i, j, incr = 1; 473 des_block ivec, tkey; 474 char *text; 475 int plen, tlen; 476 477 (void) memset(tkey.c, 0, 8); 478 (void) memset(ivec.c, 0, 8); 479 480 481 /* 482 * Concatentate the password and the mix-in string, fan-fold and XOR them 483 * to the required eight byte initial DES key. Since passwords can be 484 * expected to use mostly seven bit ASCII, left shift the password one 485 * bit in order to preserve as much key space as possible. 486 */ 487 488 #define KEYLEN sizeof (tkey.c) 489 plen = strlen(pw); 490 tlen = ((plen + len + (KEYLEN-1))/KEYLEN)*KEYLEN; 491 if ((text = malloc(tlen)) == NULL) { 492 return (0); 493 } 494 495 (void) memset(text, 0, tlen); 496 497 if (!altalg) { 498 499 /* 500 * Concatenate the password and the mix-in string, fan-fold and XOR them 501 * to the required eight byte initial DES key. Since passwords can be 502 * expected to use mostly seven bit ASCII, left shift the password one 503 * bit in order to preserve as much key space as possible. 504 */ 505 (void) memcpy(text, pw, plen); 506 (void) memcpy(&text[plen], mixin, len); 507 508 for (i = 0, j = 0; pw[j]; j++) { 509 tkey.c[i] ^= pw[j] << 1; 510 i += incr; 511 if (i == 8) { 512 i = 7; 513 incr = -incr; 514 } else if (i == -1) { 515 i = 0; 516 incr = -incr; 517 } 518 } 519 520 for (j = 0; j < len; j++) { 521 tkey.c[i] ^= mixin[j]; 522 i += incr; 523 if (i == 8) { 524 i = 7; 525 incr = -incr; 526 } else if (i == -1) { 527 i = 0; 528 incr = -incr; 529 } 530 } 531 } else { /* use alternative algorithm */ 532 (void) memcpy(text, mixin, len); 533 (void) memcpy(&text[len], pw, plen); 534 535 for (i = 0, j = 0; j < len; j++) { 536 tkey.c[i] ^= mixin[j]; 537 i += incr; 538 if (i == 8) { 539 i = 7; 540 incr = -incr; 541 } else if (i == -1) { 542 i = 0; 543 incr = -incr; 544 } 545 } 546 547 for (j = 0; pw[j]; j++) { 548 tkey.c[i] ^= pw[j] << 1; 549 i += incr; 550 if (i == 8) { 551 i = 7; 552 incr = -incr; 553 } else if (i == -1) { 554 i = 0; 555 incr = -incr; 556 } 557 } 558 } 559 des_setparity_g(&tkey); 560 561 /* 562 * Use the temporary key to produce a DES CBC checksum for the text 563 * string; cbc_crypt returns the checksum in the ivec. 564 */ 565 (void) cbc_crypt(tkey.c, text, tlen, DES_ENCRYPT|DES_HW, ivec.c); 566 des_setparity_g(&ivec); 567 free(text); 568 569 if (weak_DES_key(ivec)) { 570 ivec.c[7] ^= 0xf0; 571 /* 572 * XORing with 0xf0 preserves parity, so no need to check 573 * that again. 574 */ 575 } 576 577 (void) memcpy((*key).c, ivec.c, sizeof (ivec.c)); 578 579 return (1); 580 581 } 582 583 struct DESkey { 584 uint32_t h1; 585 uint32_t h2; 586 }; 587 588 /* 589 * Weak and semiweak keys from "Applied Cryptography", second edition, 590 * by Bruce Schneier, Wiley 1996. 591 */ 592 static struct DESkey weakDESkeys[] = { 593 /* Weak keys */ 594 {0x01010101, 0x01010101}, 595 {0x1f1f1f1f, 0x1f1f1f1f}, 596 {0xe0e0e0e0, 0xe0e0e0e0}, 597 {0xfefefefe, 0xfefefefe}, 598 /* Semiweak keys */ 599 {0x01fe01fe, 0x01fe01fe}, 600 {0x1fe01fe0, 0x0ef10ef1}, 601 {0x01e001e0, 0x01f101f1}, 602 {0x1ffe1ffe, 0x0efe0efe}, 603 {0x011f011f, 0x010e010e}, 604 {0xe0fee0fe, 0xf1fef1fe}, 605 {0xfe01fe01, 0xfe01fe01}, 606 {0xe01fe01f, 0xf10ef10e}, 607 {0xe001e001, 0xf101f101}, 608 {0xfe1ffe1f, 0xfe0efe0e}, 609 {0x1f011f01, 0x0e010e01}, 610 {0xfee0fee0, 0xfef1fef1} 611 }; 612 613 static int 614 weak_DES_key(des_block db) 615 { 616 int i; 617 618 for (i = 0; i < sizeof (weakDESkeys)/sizeof (struct DESkey); i++) { 619 if (weakDESkeys[i].h1 == db.key.high && 620 weakDESkeys[i].h2 == db.key.low) 621 return (1); 622 } 623 624 return (0); 625 } 626