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
xencrypt(secret,passwd)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
xdecrypt(secret,passwd)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
passwd2des(pw,key)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
hex2bin(len,hexnum,binnum)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
bin2hex(len,binnum,hexnum)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
hexval(c)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
xencrypt_g(char * secret,keylen_t keylen,algtype_t algtype,const char * passwd,const char netname[],char ** encrypted_secret,bool_t do_chksum)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
xdecrypt_g(char * secret,int keylen,int algtype,const char * passwd,const char netname[],bool_t do_chksum)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
passwd2des_g(const char * pw,const char * mixin,int len,des_block * key,bool_t altalg)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
weak_DES_key(des_block db)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