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
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);
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)
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
|
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
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);
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)
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
|