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 }