des.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868
  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. if (RAND_bytes(buf + l++, 1) <= 0)
  435. goto problems;
  436. }
  437. buf[l++] = rem;
  438. ex = 1;
  439. len += rem;
  440. } else
  441. l -= rem;
  442. if (cflag) {
  443. DES_cbc_cksum(buf, &cksum, (long)len, &ks, &cksum);
  444. if (!eflag) {
  445. if (feof(DES_IN))
  446. break;
  447. else
  448. continue;
  449. }
  450. }
  451. if (bflag && !flag3)
  452. for (i = 0; i < l; i += 8)
  453. DES_ecb_encrypt((DES_cblock *)&(buf[i]),
  454. (DES_cblock *)&(obuf[i]),
  455. &ks, do_encrypt);
  456. else if (flag3 && bflag)
  457. for (i = 0; i < l; i += 8)
  458. DES_ecb2_encrypt((DES_cblock *)&(buf[i]),
  459. (DES_cblock *)&(obuf[i]),
  460. &ks, &ks2, do_encrypt);
  461. else if (flag3 && !bflag) {
  462. char tmpbuf[8];
  463. if (rem)
  464. memcpy(tmpbuf, &(buf[l]), (unsigned int)rem);
  465. DES_3cbc_encrypt((DES_cblock *)buf, (DES_cblock *)obuf,
  466. (long)l, ks, ks2, &iv, &iv2, do_encrypt);
  467. if (rem)
  468. memcpy(&(buf[l]), tmpbuf, (unsigned int)rem);
  469. } else {
  470. DES_cbc_encrypt(buf, obuf, (long)l, &ks, &iv, do_encrypt);
  471. if (l >= 8)
  472. memcpy(iv, &(obuf[l - 8]), 8);
  473. }
  474. if (rem)
  475. memcpy(buf, &(buf[l]), (unsigned int)rem);
  476. i = 0;
  477. while (i < l) {
  478. if (uflag)
  479. j = uufwrite(obuf, 1, (unsigned int)l - i, DES_OUT);
  480. else
  481. j = fwrite(obuf, 1, (unsigned int)l - i, DES_OUT);
  482. if (j == -1) {
  483. perror("Write error");
  484. Exit = 7;
  485. goto problems;
  486. }
  487. i += j;
  488. }
  489. if (feof(DES_IN)) {
  490. if (uflag)
  491. uufwriteEnd(DES_OUT);
  492. break;
  493. }
  494. }
  495. } else { /* decrypt */
  496. ex = 1;
  497. for (;;) {
  498. if (ex) {
  499. if (uflag)
  500. l = uufread(buf, 1, BUFSIZE, DES_IN);
  501. else
  502. l = fread(buf, 1, BUFSIZE, DES_IN);
  503. ex = 0;
  504. rem = l % 8;
  505. l -= rem;
  506. }
  507. if (l < 0) {
  508. perror("read error");
  509. Exit = 6;
  510. goto problems;
  511. }
  512. if (bflag && !flag3)
  513. for (i = 0; i < l; i += 8)
  514. DES_ecb_encrypt((DES_cblock *)&(buf[i]),
  515. (DES_cblock *)&(obuf[i]),
  516. &ks, do_encrypt);
  517. else if (flag3 && bflag)
  518. for (i = 0; i < l; i += 8)
  519. DES_ecb2_encrypt((DES_cblock *)&(buf[i]),
  520. (DES_cblock *)&(obuf[i]),
  521. &ks, &ks2, do_encrypt);
  522. else if (flag3 && !bflag) {
  523. DES_3cbc_encrypt((DES_cblock *)buf, (DES_cblock *)obuf,
  524. (long)l, ks, ks2, &iv, &iv2, do_encrypt);
  525. } else {
  526. DES_cbc_encrypt(buf, obuf, (long)l, &ks, &iv, do_encrypt);
  527. if (l >= 8)
  528. memcpy(iv, &(buf[l - 8]), 8);
  529. }
  530. if (uflag)
  531. ll = uufread(&(buf[rem]), 1, BUFSIZE, DES_IN);
  532. else
  533. ll = fread(&(buf[rem]), 1, BUFSIZE, DES_IN);
  534. ll += rem;
  535. rem = ll % 8;
  536. ll -= rem;
  537. if (feof(DES_IN) && (ll == 0)) {
  538. last = obuf[l - 1];
  539. if ((last > 7) || (last < 0)) {
  540. fputs("The file was not decrypted correctly.\n", stderr);
  541. Exit = 8;
  542. last = 0;
  543. }
  544. l = l - 8 + last;
  545. }
  546. i = 0;
  547. if (cflag)
  548. DES_cbc_cksum(obuf,
  549. (DES_cblock *)cksum, (long)l / 8 * 8, &ks,
  550. (DES_cblock *)cksum);
  551. while (i != l) {
  552. j = fwrite(obuf, 1, (unsigned int)l - i, DES_OUT);
  553. if (j == -1) {
  554. perror("Write error");
  555. Exit = 7;
  556. goto problems;
  557. }
  558. i += j;
  559. }
  560. l = ll;
  561. if ((l == 0) && feof(DES_IN))
  562. break;
  563. }
  564. }
  565. if (cflag) {
  566. l = 0;
  567. if (cksumname[0] != '\0') {
  568. if ((O = fopen(cksumname, "w")) != NULL) {
  569. CKSUM_OUT = O;
  570. l = 1;
  571. }
  572. }
  573. for (i = 0; i < 8; i++)
  574. fprintf(CKSUM_OUT, "%02X", cksum[i]);
  575. fprintf(CKSUM_OUT, "\n");
  576. if (l)
  577. fclose(CKSUM_OUT);
  578. }
  579. problems:
  580. OPENSSL_cleanse(buf, sizeof(buf));
  581. OPENSSL_cleanse(obuf, sizeof(obuf));
  582. OPENSSL_cleanse(&ks, sizeof(ks));
  583. OPENSSL_cleanse(&ks2, sizeof(ks2));
  584. OPENSSL_cleanse(iv, sizeof(iv));
  585. OPENSSL_cleanse(iv2, sizeof(iv2));
  586. OPENSSL_cleanse(kk, sizeof(kk));
  587. OPENSSL_cleanse(k2, sizeof(k2));
  588. OPENSSL_cleanse(uubuf, sizeof(uubuf));
  589. OPENSSL_cleanse(b, sizeof(b));
  590. OPENSSL_cleanse(bb, sizeof(bb));
  591. OPENSSL_cleanse(cksum, sizeof(cksum));
  592. if (Exit)
  593. EXIT(Exit);
  594. }
  595. /* We ignore this parameter but it should be > ~50 I believe */
  596. int uufwrite(unsigned char *data, int size, unsigned int num, FILE *fp)
  597. {
  598. int i, j, left, rem, ret = num;
  599. static int start = 1;
  600. if (start) {
  601. fprintf(fp, "begin 600 %s\n",
  602. (uuname[0] == '\0') ? "text.d" : uuname);
  603. start = 0;
  604. }
  605. if (uubufnum) {
  606. if (uubufnum + num < 45) {
  607. memcpy(&(uubuf[uubufnum]), data, (unsigned int)num);
  608. uubufnum += num;
  609. return (num);
  610. } else {
  611. i = 45 - uubufnum;
  612. memcpy(&(uubuf[uubufnum]), data, (unsigned int)i);
  613. j = uuencode((unsigned char *)uubuf, 45, b);
  614. fwrite(b, 1, (unsigned int)j, fp);
  615. uubufnum = 0;
  616. data += i;
  617. num -= i;
  618. }
  619. }
  620. for (i = 0; i < (((int)num) - INUUBUFN); i += INUUBUFN) {
  621. j = uuencode(&(data[i]), INUUBUFN, b);
  622. fwrite(b, 1, (unsigned int)j, fp);
  623. }
  624. rem = (num - i) % 45;
  625. left = (num - i - rem);
  626. if (left) {
  627. j = uuencode(&(data[i]), left, b);
  628. fwrite(b, 1, (unsigned int)j, fp);
  629. i += left;
  630. }
  631. if (i != num) {
  632. memcpy(uubuf, &(data[i]), (unsigned int)rem);
  633. uubufnum = rem;
  634. }
  635. return (ret);
  636. }
  637. void uufwriteEnd(FILE *fp)
  638. {
  639. int j;
  640. static const char *end = " \nend\n";
  641. if (uubufnum != 0) {
  642. uubuf[uubufnum] = '\0';
  643. uubuf[uubufnum + 1] = '\0';
  644. uubuf[uubufnum + 2] = '\0';
  645. j = uuencode(uubuf, uubufnum, b);
  646. fwrite(b, 1, (unsigned int)j, fp);
  647. }
  648. fwrite(end, 1, strlen(end), fp);
  649. }
  650. /*
  651. * int size: should always be > ~ 60; I actually ignore this parameter :-)
  652. */
  653. int uufread(unsigned char *out, int size, unsigned int num, FILE *fp)
  654. {
  655. int i, j, tot;
  656. static int done = 0;
  657. static int valid = 0;
  658. static int start = 1;
  659. if (start) {
  660. for (;;) {
  661. b[0] = '\0';
  662. fgets((char *)b, 300, fp);
  663. if (b[0] == '\0') {
  664. fprintf(stderr, "no 'begin' found in uuencoded input\n");
  665. return (-1);
  666. }
  667. if (strncmp((char *)b, "begin ", 6) == 0)
  668. break;
  669. }
  670. start = 0;
  671. }
  672. if (done)
  673. return (0);
  674. tot = 0;
  675. if (valid) {
  676. memcpy(out, bb, (unsigned int)valid);
  677. tot = valid;
  678. valid = 0;
  679. }
  680. for (;;) {
  681. b[0] = '\0';
  682. fgets((char *)b, 300, fp);
  683. if (b[0] == '\0')
  684. break;
  685. i = strlen((char *)b);
  686. if ((b[0] == 'e') && (b[1] == 'n') && (b[2] == 'd')) {
  687. done = 1;
  688. while (!feof(fp)) {
  689. fgets((char *)b, 300, fp);
  690. }
  691. break;
  692. }
  693. i = uudecode(b, i, bb);
  694. if (i < 0)
  695. break;
  696. if ((i + tot + 8) > num) {
  697. /* num to copy to make it a multiple of 8 */
  698. j = (num / 8 * 8) - tot - 8;
  699. memcpy(&(out[tot]), bb, (unsigned int)j);
  700. tot += j;
  701. memcpy(bb, &(bb[j]), (unsigned int)i - j);
  702. valid = i - j;
  703. break;
  704. }
  705. memcpy(&(out[tot]), bb, (unsigned int)i);
  706. tot += i;
  707. }
  708. return (tot);
  709. }
  710. #define ccc2l(c,l) (l =((DES_LONG)(*((c)++)))<<16, \
  711. l|=((DES_LONG)(*((c)++)))<< 8, \
  712. l|=((DES_LONG)(*((c)++))))
  713. #define l2ccc(l,c) (*((c)++)=(unsigned char)(((l)>>16)&0xff), \
  714. *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
  715. *((c)++)=(unsigned char)(((l) )&0xff))
  716. int uuencode(unsigned char *in, int num, unsigned char *out)
  717. {
  718. int j, i, n, tot = 0;
  719. DES_LONG l;
  720. register unsigned char *p;
  721. p = out;
  722. for (j = 0; j < num; j += 45) {
  723. if (j + 45 > num)
  724. i = (num - j);
  725. else
  726. i = 45;
  727. *(p++) = i + ' ';
  728. for (n = 0; n < i; n += 3) {
  729. ccc2l(in, l);
  730. *(p++) = ((l >> 18) & 0x3f) + ' ';
  731. *(p++) = ((l >> 12) & 0x3f) + ' ';
  732. *(p++) = ((l >> 6) & 0x3f) + ' ';
  733. *(p++) = ((l) & 0x3f) + ' ';
  734. tot += 4;
  735. }
  736. *(p++) = '\n';
  737. tot += 2;
  738. }
  739. *p = '\0';
  740. l = 0;
  741. return (tot);
  742. }
  743. int uudecode(unsigned char *in, int num, unsigned char *out)
  744. {
  745. int j, i, k;
  746. unsigned int n = 0, space = 0;
  747. DES_LONG l;
  748. DES_LONG w, x, y, z;
  749. unsigned int blank = (unsigned int)'\n' - ' ';
  750. for (j = 0; j < num;) {
  751. n = *(in++) - ' ';
  752. if (n == blank) {
  753. n = 0;
  754. in--;
  755. }
  756. if (n > 60) {
  757. fprintf(stderr, "uuencoded line length too long\n");
  758. return (-1);
  759. }
  760. j++;
  761. for (i = 0; i < n; j += 4, i += 3) {
  762. /*
  763. * the following is for cases where spaces are removed from
  764. * lines.
  765. */
  766. if (space) {
  767. w = x = y = z = 0;
  768. } else {
  769. w = *(in++) - ' ';
  770. x = *(in++) - ' ';
  771. y = *(in++) - ' ';
  772. z = *(in++) - ' ';
  773. }
  774. if ((w > 63) || (x > 63) || (y > 63) || (z > 63)) {
  775. k = 0;
  776. if (w == blank)
  777. k = 1;
  778. if (x == blank)
  779. k = 2;
  780. if (y == blank)
  781. k = 3;
  782. if (z == blank)
  783. k = 4;
  784. space = 1;
  785. switch (k) {
  786. case 1:
  787. w = 0;
  788. in--;
  789. case 2:
  790. x = 0;
  791. in--;
  792. case 3:
  793. y = 0;
  794. in--;
  795. case 4:
  796. z = 0;
  797. in--;
  798. break;
  799. case 0:
  800. space = 0;
  801. fprintf(stderr, "bad uuencoded data values\n");
  802. w = x = y = z = 0;
  803. return (-1);
  804. break;
  805. }
  806. }
  807. l = (w << 18) | (x << 12) | (y << 6) | (z);
  808. l2ccc(l, out);
  809. }
  810. if (*(in++) != '\n') {
  811. fprintf(stderr, "missing nl in uuencoded line\n");
  812. w = x = y = z = 0;
  813. return (-1);
  814. }
  815. j++;
  816. }
  817. *out = '\0';
  818. w = x = y = z = 0;
  819. return (n);
  820. }