2
0

des.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
  1. /* crypto/des/des.c */
  2. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  3. * All rights reserved.
  4. *
  5. * This package is an SSL implementation written
  6. * by Eric Young (eay@cryptsoft.com).
  7. * The implementation was written so as to conform with Netscapes SSL.
  8. *
  9. * This library is free for commercial and non-commercial use as long as
  10. * the following conditions are aheared to. The following conditions
  11. * apply to all code found in this distribution, be it the RC4, RSA,
  12. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  13. * included with this distribution is covered by the same copyright terms
  14. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  15. *
  16. * Copyright remains Eric Young's, and as such any Copyright notices in
  17. * the code are not to be removed.
  18. * If this package is used in a product, Eric Young should be given attribution
  19. * as the author of the parts of the library used.
  20. * This can be in the form of a textual message at program startup or
  21. * in documentation (online or textual) provided with the package.
  22. *
  23. * Redistribution and use in source and binary forms, with or without
  24. * modification, are permitted provided that the following conditions
  25. * are met:
  26. * 1. Redistributions of source code must retain the copyright
  27. * notice, this list of conditions and the following disclaimer.
  28. * 2. Redistributions in binary form must reproduce the above copyright
  29. * notice, this list of conditions and the following disclaimer in the
  30. * documentation and/or other materials provided with the distribution.
  31. * 3. All advertising materials mentioning features or use of this software
  32. * must display the following acknowledgement:
  33. * "This product includes cryptographic software written by
  34. * Eric Young (eay@cryptsoft.com)"
  35. * The word 'cryptographic' can be left out if the rouines from the library
  36. * being used are not cryptographic related :-).
  37. * 4. If you include any Windows specific code (or a derivative thereof) from
  38. * the apps directory (application code) you must include an acknowledgement:
  39. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  40. *
  41. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  42. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  44. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  45. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  47. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  49. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  50. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  51. * SUCH DAMAGE.
  52. *
  53. * The licence and distribution terms for any publically available version or
  54. * derivative of this code cannot be changed. i.e. this code cannot simply be
  55. * copied and put under another distribution licence
  56. * [including the GNU Public Licence.]
  57. */
  58. #include <stdio.h>
  59. #include <stdlib.h>
  60. #include <string.h>
  61. #include <openssl/opensslconf.h>
  62. #ifndef OPENSSL_SYS_MSDOS
  63. # ifndef OPENSSL_SYS_VMS
  64. # include OPENSSL_UNISTD
  65. # else /* OPENSSL_SYS_VMS */
  66. # ifdef __DECC
  67. # include <unistd.h>
  68. # else /* not __DECC */
  69. # include <math.h>
  70. # endif /* __DECC */
  71. # endif /* OPENSSL_SYS_VMS */
  72. #else /* OPENSSL_SYS_MSDOS */
  73. # include <io.h>
  74. #endif
  75. #include <time.h>
  76. #include "des_ver.h"
  77. #ifdef OPENSSL_SYS_VMS
  78. # include <types.h>
  79. # include <stat.h>
  80. #else
  81. # ifndef _IRIX
  82. # include <sys/types.h>
  83. # endif
  84. # include <sys/stat.h>
  85. #endif
  86. #include <openssl/des.h>
  87. #include <openssl/rand.h>
  88. #include <openssl/ui_compat.h>
  89. void usage(void);
  90. void doencryption(void);
  91. int uufwrite(unsigned char *data, int size, unsigned int num, FILE *fp);
  92. void uufwriteEnd(FILE *fp);
  93. int uufread(unsigned char *out, int size, unsigned int num, FILE *fp);
  94. int uuencode(unsigned char *in, int num, unsigned char *out);
  95. int uudecode(unsigned char *in, int num, unsigned char *out);
  96. void DES_3cbc_encrypt(DES_cblock *input, DES_cblock *output, long length,
  97. DES_key_schedule sk1, DES_key_schedule sk2,
  98. DES_cblock *ivec1, DES_cblock *ivec2, int enc);
  99. #ifdef OPENSSL_SYS_VMS
  100. # define EXIT(a) exit(a&0x10000000L)
  101. #else
  102. # define EXIT(a) exit(a)
  103. #endif
  104. #define BUFSIZE (8*1024)
  105. #define VERIFY 1
  106. #define KEYSIZ 8
  107. #define KEYSIZB 1024 /* should hit tty line limit first :-) */
  108. char key[KEYSIZB + 1];
  109. int do_encrypt, longk = 0;
  110. FILE *DES_IN, *DES_OUT, *CKSUM_OUT;
  111. char uuname[200];
  112. unsigned char uubuf[50];
  113. int uubufnum = 0;
  114. #define INUUBUFN (45*100)
  115. #define OUTUUBUF (65*100)
  116. unsigned char b[OUTUUBUF];
  117. unsigned char bb[300];
  118. DES_cblock cksum = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  119. char cksumname[200] = "";
  120. int vflag, cflag, eflag, dflag, kflag, bflag, fflag, sflag, uflag, flag3,
  121. hflag, error;
  122. int main(int argc, char **argv)
  123. {
  124. int i;
  125. struct stat ins, outs;
  126. char *p;
  127. char *in = NULL, *out = NULL;
  128. vflag = cflag = eflag = dflag = kflag = hflag = bflag = fflag = sflag =
  129. uflag = flag3 = 0;
  130. error = 0;
  131. memset(key, 0, sizeof(key));
  132. for (i = 1; i < argc; i++) {
  133. p = argv[i];
  134. if ((p[0] == '-') && (p[1] != '\0')) {
  135. p++;
  136. while (*p) {
  137. switch (*(p++)) {
  138. case '3':
  139. flag3 = 1;
  140. longk = 1;
  141. break;
  142. case 'c':
  143. cflag = 1;
  144. strncpy(cksumname, p, 200);
  145. cksumname[sizeof(cksumname) - 1] = '\0';
  146. p += strlen(cksumname);
  147. break;
  148. case 'C':
  149. cflag = 1;
  150. longk = 1;
  151. strncpy(cksumname, p, 200);
  152. cksumname[sizeof(cksumname) - 1] = '\0';
  153. p += strlen(cksumname);
  154. break;
  155. case 'e':
  156. eflag = 1;
  157. break;
  158. case 'v':
  159. vflag = 1;
  160. break;
  161. case 'E':
  162. eflag = 1;
  163. longk = 1;
  164. break;
  165. case 'd':
  166. dflag = 1;
  167. break;
  168. case 'D':
  169. dflag = 1;
  170. longk = 1;
  171. break;
  172. case 'b':
  173. bflag = 1;
  174. break;
  175. case 'f':
  176. fflag = 1;
  177. break;
  178. case 's':
  179. sflag = 1;
  180. break;
  181. case 'u':
  182. uflag = 1;
  183. strncpy(uuname, p, 200);
  184. uuname[sizeof(uuname) - 1] = '\0';
  185. p += strlen(uuname);
  186. break;
  187. case 'h':
  188. hflag = 1;
  189. break;
  190. case 'k':
  191. kflag = 1;
  192. if ((i + 1) == argc) {
  193. fputs("must have a key with the -k option\n", stderr);
  194. error = 1;
  195. } else {
  196. int j;
  197. i++;
  198. strncpy(key, argv[i], KEYSIZB);
  199. for (j = strlen(argv[i]) - 1; j >= 0; j--)
  200. argv[i][j] = '\0';
  201. }
  202. break;
  203. default:
  204. fprintf(stderr, "'%c' unknown flag\n", p[-1]);
  205. error = 1;
  206. break;
  207. }
  208. }
  209. } else {
  210. if (in == NULL)
  211. in = argv[i];
  212. else if (out == NULL)
  213. out = argv[i];
  214. else
  215. error = 1;
  216. }
  217. }
  218. if (error)
  219. usage();
  220. /*-
  221. * We either
  222. * do checksum or
  223. * do encrypt or
  224. * do decrypt or
  225. * do decrypt then ckecksum or
  226. * do checksum then encrypt
  227. */
  228. if (((eflag + dflag) == 1) || cflag) {
  229. if (eflag)
  230. do_encrypt = DES_ENCRYPT;
  231. if (dflag)
  232. do_encrypt = DES_DECRYPT;
  233. } else {
  234. if (vflag) {
  235. #ifndef _Windows
  236. fprintf(stderr, "des(1) built with %s\n", libdes_version);
  237. #endif
  238. EXIT(1);
  239. } else
  240. usage();
  241. }
  242. #ifndef _Windows
  243. if (vflag)
  244. fprintf(stderr, "des(1) built with %s\n", libdes_version);
  245. #endif
  246. if ((in != NULL) && (out != NULL) &&
  247. #ifndef OPENSSL_SYS_MSDOS
  248. (stat(in, &ins) != -1) &&
  249. (stat(out, &outs) != -1) &&
  250. (ins.st_dev == outs.st_dev) && (ins.st_ino == outs.st_ino))
  251. #else /* OPENSSL_SYS_MSDOS */
  252. (strcmp(in, out) == 0))
  253. #endif
  254. {
  255. fputs("input and output file are the same\n", stderr);
  256. EXIT(3);
  257. }
  258. if (!kflag)
  259. if (des_read_pw_string
  260. (key, KEYSIZB + 1, "Enter key:", eflag ? VERIFY : 0)) {
  261. fputs("password error\n", stderr);
  262. EXIT(2);
  263. }
  264. if (in == NULL)
  265. DES_IN = stdin;
  266. else if ((DES_IN = fopen(in, "r")) == NULL) {
  267. perror("opening input file");
  268. EXIT(4);
  269. }
  270. CKSUM_OUT = stdout;
  271. if (out == NULL) {
  272. DES_OUT = stdout;
  273. CKSUM_OUT = stderr;
  274. } else if ((DES_OUT = fopen(out, "w")) == NULL) {
  275. perror("opening output file");
  276. EXIT(5);
  277. }
  278. #ifdef OPENSSL_SYS_MSDOS
  279. /* This should set the file to binary mode. */
  280. {
  281. # include <fcntl.h>
  282. if (!(uflag && dflag))
  283. setmode(fileno(DES_IN), O_BINARY);
  284. if (!(uflag && eflag))
  285. setmode(fileno(DES_OUT), O_BINARY);
  286. }
  287. #endif
  288. doencryption();
  289. fclose(DES_IN);
  290. fclose(DES_OUT);
  291. EXIT(0);
  292. }
  293. void usage(void)
  294. {
  295. char **u;
  296. static const char *Usage[] = {
  297. "des <options> [input-file [output-file]]",
  298. "options:",
  299. "-v : des(1) version number",
  300. "-e : encrypt using SunOS compatible user key to DES key conversion.",
  301. "-E : encrypt ",
  302. "-d : decrypt using SunOS compatible user key to DES key conversion.",
  303. "-D : decrypt ",
  304. "-c[ckname] : generate a cbc_cksum using SunOS compatible user key to",
  305. " DES key conversion and output to ckname (stdout default,",
  306. " stderr if data being output on stdout). The checksum is",
  307. " generated before encryption and after decryption if used",
  308. " in conjunction with -[eEdD].",
  309. "-C[ckname] : generate a cbc_cksum as for -c but compatible with -[ED].",
  310. "-k key : use key 'key'",
  311. "-h : the key that is entered will be a hexadecimal number",
  312. " that is used directly as the des key",
  313. "-u[uuname] : input file is uudecoded if -[dD] or output uuencoded data if -[eE]",
  314. " (uuname is the filename to put in the uuencode header).",
  315. "-b : encrypt using DES in ecb encryption mode, the default is cbc mode.",
  316. "-3 : encrypt using triple DES encryption. This uses 2 keys",
  317. " generated from the input key. If the input key is less",
  318. " than 8 characters long, this is equivalent to normal",
  319. " encryption. Default is triple cbc, -b makes it triple ecb.",
  320. NULL
  321. };
  322. for (u = (char **)Usage; *u; u++) {
  323. fputs(*u, stderr);
  324. fputc('\n', stderr);
  325. }
  326. EXIT(1);
  327. }
  328. void doencryption(void)
  329. {
  330. #ifdef _LIBC
  331. extern unsigned long time();
  332. #endif
  333. register int i;
  334. DES_key_schedule ks, ks2;
  335. DES_cblock iv, iv2;
  336. char *p;
  337. int num = 0, j, k, l, rem, ll, len, last, ex = 0;
  338. DES_cblock kk, k2;
  339. FILE *O;
  340. int Exit = 0;
  341. #ifndef OPENSSL_SYS_MSDOS
  342. static unsigned char buf[BUFSIZE + 8], obuf[BUFSIZE + 8];
  343. #else
  344. static unsigned char *buf = NULL, *obuf = NULL;
  345. if (buf == NULL) {
  346. if (((buf = OPENSSL_malloc(BUFSIZE + 8)) == NULL) ||
  347. ((obuf = OPENSSL_malloc(BUFSIZE + 8)) == NULL)) {
  348. fputs("Not enough memory\n", stderr);
  349. Exit = 10;
  350. goto problems;
  351. }
  352. }
  353. #endif
  354. if (hflag) {
  355. j = (flag3 ? 16 : 8);
  356. p = key;
  357. for (i = 0; i < j; i++) {
  358. k = 0;
  359. if ((*p <= '9') && (*p >= '0'))
  360. k = (*p - '0') << 4;
  361. else if ((*p <= 'f') && (*p >= 'a'))
  362. k = (*p - 'a' + 10) << 4;
  363. else if ((*p <= 'F') && (*p >= 'A'))
  364. k = (*p - 'A' + 10) << 4;
  365. else {
  366. fputs("Bad hex key\n", stderr);
  367. Exit = 9;
  368. goto problems;
  369. }
  370. p++;
  371. if ((*p <= '9') && (*p >= '0'))
  372. k |= (*p - '0');
  373. else if ((*p <= 'f') && (*p >= 'a'))
  374. k |= (*p - 'a' + 10);
  375. else if ((*p <= 'F') && (*p >= 'A'))
  376. k |= (*p - 'A' + 10);
  377. else {
  378. fputs("Bad hex key\n", stderr);
  379. Exit = 9;
  380. goto problems;
  381. }
  382. p++;
  383. if (i < 8)
  384. kk[i] = k;
  385. else
  386. k2[i - 8] = k;
  387. }
  388. DES_set_key_unchecked(&k2, &ks2);
  389. OPENSSL_cleanse(k2, sizeof(k2));
  390. } else if (longk || flag3) {
  391. if (flag3) {
  392. DES_string_to_2keys(key, &kk, &k2);
  393. DES_set_key_unchecked(&k2, &ks2);
  394. OPENSSL_cleanse(k2, sizeof(k2));
  395. } else
  396. DES_string_to_key(key, &kk);
  397. } else
  398. for (i = 0; i < KEYSIZ; i++) {
  399. l = 0;
  400. k = key[i];
  401. for (j = 0; j < 8; j++) {
  402. if (k & 1)
  403. l++;
  404. k >>= 1;
  405. }
  406. if (l & 1)
  407. kk[i] = key[i] & 0x7f;
  408. else
  409. kk[i] = key[i] | 0x80;
  410. }
  411. DES_set_key_unchecked(&kk, &ks);
  412. OPENSSL_cleanse(key, sizeof(key));
  413. OPENSSL_cleanse(kk, sizeof(kk));
  414. /* woops - A bug that does not showup under unix :-( */
  415. memset(iv, 0, sizeof(iv));
  416. memset(iv2, 0, sizeof(iv2));
  417. l = 1;
  418. rem = 0;
  419. /* first read */
  420. if (eflag || (!dflag && cflag)) {
  421. for (;;) {
  422. num = l = fread(&(buf[rem]), 1, BUFSIZE, DES_IN);
  423. l += rem;
  424. num += rem;
  425. if (l < 0) {
  426. perror("read error");
  427. Exit = 6;
  428. goto problems;
  429. }
  430. rem = l % 8;
  431. len = l - rem;
  432. if (feof(DES_IN)) {
  433. for (i = 7 - rem; i > 0; i--)
  434. RAND_pseudo_bytes(buf + l++, 1);
  435. buf[l++] = rem;
  436. ex = 1;
  437. len += rem;
  438. } else
  439. l -= rem;
  440. if (cflag) {
  441. DES_cbc_cksum(buf, &cksum, (long)len, &ks, &cksum);
  442. if (!eflag) {
  443. if (feof(DES_IN))
  444. break;
  445. else
  446. continue;
  447. }
  448. }
  449. if (bflag && !flag3)
  450. for (i = 0; i < l; i += 8)
  451. DES_ecb_encrypt((DES_cblock *)&(buf[i]),
  452. (DES_cblock *)&(obuf[i]),
  453. &ks, do_encrypt);
  454. else if (flag3 && bflag)
  455. for (i = 0; i < l; i += 8)
  456. DES_ecb2_encrypt((DES_cblock *)&(buf[i]),
  457. (DES_cblock *)&(obuf[i]),
  458. &ks, &ks2, do_encrypt);
  459. else if (flag3 && !bflag) {
  460. char tmpbuf[8];
  461. if (rem)
  462. memcpy(tmpbuf, &(buf[l]), (unsigned int)rem);
  463. DES_3cbc_encrypt((DES_cblock *)buf, (DES_cblock *)obuf,
  464. (long)l, ks, ks2, &iv, &iv2, do_encrypt);
  465. if (rem)
  466. memcpy(&(buf[l]), tmpbuf, (unsigned int)rem);
  467. } else {
  468. DES_cbc_encrypt(buf, obuf, (long)l, &ks, &iv, do_encrypt);
  469. if (l >= 8)
  470. memcpy(iv, &(obuf[l - 8]), 8);
  471. }
  472. if (rem)
  473. memcpy(buf, &(buf[l]), (unsigned int)rem);
  474. i = 0;
  475. while (i < l) {
  476. if (uflag)
  477. j = uufwrite(obuf, 1, (unsigned int)l - i, DES_OUT);
  478. else
  479. j = fwrite(obuf, 1, (unsigned int)l - i, DES_OUT);
  480. if (j == -1) {
  481. perror("Write error");
  482. Exit = 7;
  483. goto problems;
  484. }
  485. i += j;
  486. }
  487. if (feof(DES_IN)) {
  488. if (uflag)
  489. uufwriteEnd(DES_OUT);
  490. break;
  491. }
  492. }
  493. } else { /* decrypt */
  494. ex = 1;
  495. for (;;) {
  496. if (ex) {
  497. if (uflag)
  498. l = uufread(buf, 1, BUFSIZE, DES_IN);
  499. else
  500. l = fread(buf, 1, BUFSIZE, DES_IN);
  501. ex = 0;
  502. rem = l % 8;
  503. l -= rem;
  504. }
  505. if (l < 0) {
  506. perror("read error");
  507. Exit = 6;
  508. goto problems;
  509. }
  510. if (bflag && !flag3)
  511. for (i = 0; i < l; i += 8)
  512. DES_ecb_encrypt((DES_cblock *)&(buf[i]),
  513. (DES_cblock *)&(obuf[i]),
  514. &ks, do_encrypt);
  515. else if (flag3 && bflag)
  516. for (i = 0; i < l; i += 8)
  517. DES_ecb2_encrypt((DES_cblock *)&(buf[i]),
  518. (DES_cblock *)&(obuf[i]),
  519. &ks, &ks2, do_encrypt);
  520. else if (flag3 && !bflag) {
  521. DES_3cbc_encrypt((DES_cblock *)buf, (DES_cblock *)obuf,
  522. (long)l, ks, ks2, &iv, &iv2, do_encrypt);
  523. } else {
  524. DES_cbc_encrypt(buf, obuf, (long)l, &ks, &iv, do_encrypt);
  525. if (l >= 8)
  526. memcpy(iv, &(buf[l - 8]), 8);
  527. }
  528. if (uflag)
  529. ll = uufread(&(buf[rem]), 1, BUFSIZE, DES_IN);
  530. else
  531. ll = fread(&(buf[rem]), 1, BUFSIZE, DES_IN);
  532. ll += rem;
  533. rem = ll % 8;
  534. ll -= rem;
  535. if (feof(DES_IN) && (ll == 0)) {
  536. last = obuf[l - 1];
  537. if ((last > 7) || (last < 0)) {
  538. fputs("The file was not decrypted correctly.\n", stderr);
  539. Exit = 8;
  540. last = 0;
  541. }
  542. l = l - 8 + last;
  543. }
  544. i = 0;
  545. if (cflag)
  546. DES_cbc_cksum(obuf,
  547. (DES_cblock *)cksum, (long)l / 8 * 8, &ks,
  548. (DES_cblock *)cksum);
  549. while (i != l) {
  550. j = fwrite(obuf, 1, (unsigned int)l - i, DES_OUT);
  551. if (j == -1) {
  552. perror("Write error");
  553. Exit = 7;
  554. goto problems;
  555. }
  556. i += j;
  557. }
  558. l = ll;
  559. if ((l == 0) && feof(DES_IN))
  560. break;
  561. }
  562. }
  563. if (cflag) {
  564. l = 0;
  565. if (cksumname[0] != '\0') {
  566. if ((O = fopen(cksumname, "w")) != NULL) {
  567. CKSUM_OUT = O;
  568. l = 1;
  569. }
  570. }
  571. for (i = 0; i < 8; i++)
  572. fprintf(CKSUM_OUT, "%02X", cksum[i]);
  573. fprintf(CKSUM_OUT, "\n");
  574. if (l)
  575. fclose(CKSUM_OUT);
  576. }
  577. problems:
  578. OPENSSL_cleanse(buf, sizeof(buf));
  579. OPENSSL_cleanse(obuf, sizeof(obuf));
  580. OPENSSL_cleanse(&ks, sizeof(ks));
  581. OPENSSL_cleanse(&ks2, sizeof(ks2));
  582. OPENSSL_cleanse(iv, sizeof(iv));
  583. OPENSSL_cleanse(iv2, sizeof(iv2));
  584. OPENSSL_cleanse(kk, sizeof(kk));
  585. OPENSSL_cleanse(k2, sizeof(k2));
  586. OPENSSL_cleanse(uubuf, sizeof(uubuf));
  587. OPENSSL_cleanse(b, sizeof(b));
  588. OPENSSL_cleanse(bb, sizeof(bb));
  589. OPENSSL_cleanse(cksum, sizeof(cksum));
  590. if (Exit)
  591. EXIT(Exit);
  592. }
  593. /* We ignore this parameter but it should be > ~50 I believe */
  594. int uufwrite(unsigned char *data, int size, unsigned int num, FILE *fp)
  595. {
  596. int i, j, left, rem, ret = num;
  597. static int start = 1;
  598. if (start) {
  599. fprintf(fp, "begin 600 %s\n",
  600. (uuname[0] == '\0') ? "text.d" : uuname);
  601. start = 0;
  602. }
  603. if (uubufnum) {
  604. if (uubufnum + num < 45) {
  605. memcpy(&(uubuf[uubufnum]), data, (unsigned int)num);
  606. uubufnum += num;
  607. return (num);
  608. } else {
  609. i = 45 - uubufnum;
  610. memcpy(&(uubuf[uubufnum]), data, (unsigned int)i);
  611. j = uuencode((unsigned char *)uubuf, 45, b);
  612. fwrite(b, 1, (unsigned int)j, fp);
  613. uubufnum = 0;
  614. data += i;
  615. num -= i;
  616. }
  617. }
  618. for (i = 0; i < (((int)num) - INUUBUFN); i += INUUBUFN) {
  619. j = uuencode(&(data[i]), INUUBUFN, b);
  620. fwrite(b, 1, (unsigned int)j, fp);
  621. }
  622. rem = (num - i) % 45;
  623. left = (num - i - rem);
  624. if (left) {
  625. j = uuencode(&(data[i]), left, b);
  626. fwrite(b, 1, (unsigned int)j, fp);
  627. i += left;
  628. }
  629. if (i != num) {
  630. memcpy(uubuf, &(data[i]), (unsigned int)rem);
  631. uubufnum = rem;
  632. }
  633. return (ret);
  634. }
  635. void uufwriteEnd(FILE *fp)
  636. {
  637. int j;
  638. static const char *end = " \nend\n";
  639. if (uubufnum != 0) {
  640. uubuf[uubufnum] = '\0';
  641. uubuf[uubufnum + 1] = '\0';
  642. uubuf[uubufnum + 2] = '\0';
  643. j = uuencode(uubuf, uubufnum, b);
  644. fwrite(b, 1, (unsigned int)j, fp);
  645. }
  646. fwrite(end, 1, strlen(end), fp);
  647. }
  648. /*
  649. * int size: should always be > ~ 60; I actually ignore this parameter :-)
  650. */
  651. int uufread(unsigned char *out, int size, unsigned int num, FILE *fp)
  652. {
  653. int i, j, tot;
  654. static int done = 0;
  655. static int valid = 0;
  656. static int start = 1;
  657. if (start) {
  658. for (;;) {
  659. b[0] = '\0';
  660. fgets((char *)b, 300, fp);
  661. if (b[0] == '\0') {
  662. fprintf(stderr, "no 'begin' found in uuencoded input\n");
  663. return (-1);
  664. }
  665. if (strncmp((char *)b, "begin ", 6) == 0)
  666. break;
  667. }
  668. start = 0;
  669. }
  670. if (done)
  671. return (0);
  672. tot = 0;
  673. if (valid) {
  674. memcpy(out, bb, (unsigned int)valid);
  675. tot = valid;
  676. valid = 0;
  677. }
  678. for (;;) {
  679. b[0] = '\0';
  680. fgets((char *)b, 300, fp);
  681. if (b[0] == '\0')
  682. break;
  683. i = strlen((char *)b);
  684. if ((b[0] == 'e') && (b[1] == 'n') && (b[2] == 'd')) {
  685. done = 1;
  686. while (!feof(fp)) {
  687. fgets((char *)b, 300, fp);
  688. }
  689. break;
  690. }
  691. i = uudecode(b, i, bb);
  692. if (i < 0)
  693. break;
  694. if ((i + tot + 8) > num) {
  695. /* num to copy to make it a multiple of 8 */
  696. j = (num / 8 * 8) - tot - 8;
  697. memcpy(&(out[tot]), bb, (unsigned int)j);
  698. tot += j;
  699. memcpy(bb, &(bb[j]), (unsigned int)i - j);
  700. valid = i - j;
  701. break;
  702. }
  703. memcpy(&(out[tot]), bb, (unsigned int)i);
  704. tot += i;
  705. }
  706. return (tot);
  707. }
  708. #define ccc2l(c,l) (l =((DES_LONG)(*((c)++)))<<16, \
  709. l|=((DES_LONG)(*((c)++)))<< 8, \
  710. l|=((DES_LONG)(*((c)++))))
  711. #define l2ccc(l,c) (*((c)++)=(unsigned char)(((l)>>16)&0xff), \
  712. *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
  713. *((c)++)=(unsigned char)(((l) )&0xff))
  714. int uuencode(unsigned char *in, int num, unsigned char *out)
  715. {
  716. int j, i, n, tot = 0;
  717. DES_LONG l;
  718. register unsigned char *p;
  719. p = out;
  720. for (j = 0; j < num; j += 45) {
  721. if (j + 45 > num)
  722. i = (num - j);
  723. else
  724. i = 45;
  725. *(p++) = i + ' ';
  726. for (n = 0; n < i; n += 3) {
  727. ccc2l(in, l);
  728. *(p++) = ((l >> 18) & 0x3f) + ' ';
  729. *(p++) = ((l >> 12) & 0x3f) + ' ';
  730. *(p++) = ((l >> 6) & 0x3f) + ' ';
  731. *(p++) = ((l) & 0x3f) + ' ';
  732. tot += 4;
  733. }
  734. *(p++) = '\n';
  735. tot += 2;
  736. }
  737. *p = '\0';
  738. l = 0;
  739. return (tot);
  740. }
  741. int uudecode(unsigned char *in, int num, unsigned char *out)
  742. {
  743. int j, i, k;
  744. unsigned int n = 0, space = 0;
  745. DES_LONG l;
  746. DES_LONG w, x, y, z;
  747. unsigned int blank = (unsigned int)'\n' - ' ';
  748. for (j = 0; j < num;) {
  749. n = *(in++) - ' ';
  750. if (n == blank) {
  751. n = 0;
  752. in--;
  753. }
  754. if (n > 60) {
  755. fprintf(stderr, "uuencoded line length too long\n");
  756. return (-1);
  757. }
  758. j++;
  759. for (i = 0; i < n; j += 4, i += 3) {
  760. /*
  761. * the following is for cases where spaces are removed from
  762. * lines.
  763. */
  764. if (space) {
  765. w = x = y = z = 0;
  766. } else {
  767. w = *(in++) - ' ';
  768. x = *(in++) - ' ';
  769. y = *(in++) - ' ';
  770. z = *(in++) - ' ';
  771. }
  772. if ((w > 63) || (x > 63) || (y > 63) || (z > 63)) {
  773. k = 0;
  774. if (w == blank)
  775. k = 1;
  776. if (x == blank)
  777. k = 2;
  778. if (y == blank)
  779. k = 3;
  780. if (z == blank)
  781. k = 4;
  782. space = 1;
  783. switch (k) {
  784. case 1:
  785. w = 0;
  786. in--;
  787. case 2:
  788. x = 0;
  789. in--;
  790. case 3:
  791. y = 0;
  792. in--;
  793. case 4:
  794. z = 0;
  795. in--;
  796. break;
  797. case 0:
  798. space = 0;
  799. fprintf(stderr, "bad uuencoded data values\n");
  800. w = x = y = z = 0;
  801. return (-1);
  802. break;
  803. }
  804. }
  805. l = (w << 18) | (x << 12) | (y << 6) | (z);
  806. l2ccc(l, out);
  807. }
  808. if (*(in++) != '\n') {
  809. fprintf(stderr, "missing nl in uuencoded line\n");
  810. w = x = y = z = 0;
  811. return (-1);
  812. }
  813. j++;
  814. }
  815. *out = '\0';
  816. w = x = y = z = 0;
  817. return (n);
  818. }