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