des.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928
  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. void usage(void);
  89. void doencryption(void);
  90. int uufwrite(unsigned char *data, int size, unsigned int num, FILE *fp);
  91. void uufwriteEnd(FILE *fp);
  92. int uufread(unsigned char *out,int size,unsigned int num,FILE *fp);
  93. int uuencode(unsigned char *in,int num,unsigned char *out);
  94. int uudecode(unsigned char *in,int num,unsigned char *out);
  95. void des_3cbc_encrypt(des_cblock *input,des_cblock *output,long length,
  96. des_key_schedule sk1,des_key_schedule sk2,
  97. des_cblock *ivec1,des_cblock *ivec2,int enc);
  98. #ifdef OPENSSL_SYS_VMS
  99. #define EXIT(a) exit(a&0x10000000L)
  100. #else
  101. #define EXIT(a) exit(a)
  102. #endif
  103. #define BUFSIZE (8*1024)
  104. #define VERIFY 1
  105. #define KEYSIZ 8
  106. #define KEYSIZB 1024 /* should hit tty line limit first :-) */
  107. char key[KEYSIZB+1];
  108. int do_encrypt,longk=0;
  109. FILE *DES_IN,*DES_OUT,*CKSUM_OUT;
  110. char uuname[200];
  111. unsigned char uubuf[50];
  112. int uubufnum=0;
  113. #define INUUBUFN (45*100)
  114. #define OUTUUBUF (65*100)
  115. unsigned char b[OUTUUBUF];
  116. unsigned char bb[300];
  117. des_cblock cksum={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  118. char cksumname[200]="";
  119. int vflag,cflag,eflag,dflag,kflag,bflag,fflag,sflag,uflag,flag3,hflag,error;
  120. int main(int argc, char **argv)
  121. {
  122. int i;
  123. struct stat ins,outs;
  124. char *p;
  125. char *in=NULL,*out=NULL;
  126. vflag=cflag=eflag=dflag=kflag=hflag=bflag=fflag=sflag=uflag=flag3=0;
  127. error=0;
  128. memset(key,0,sizeof(key));
  129. for (i=1; i<argc; i++)
  130. {
  131. p=argv[i];
  132. if ((p[0] == '-') && (p[1] != '\0'))
  133. {
  134. p++;
  135. while (*p)
  136. {
  137. switch (*(p++))
  138. {
  139. case '3':
  140. flag3=1;
  141. longk=1;
  142. break;
  143. case 'c':
  144. cflag=1;
  145. strncpy(cksumname,p,200);
  146. p+=strlen(cksumname);
  147. break;
  148. case 'C':
  149. cflag=1;
  150. longk=1;
  151. strncpy(cksumname,p,200);
  152. p+=strlen(cksumname);
  153. break;
  154. case 'e':
  155. eflag=1;
  156. break;
  157. case 'v':
  158. vflag=1;
  159. break;
  160. case 'E':
  161. eflag=1;
  162. longk=1;
  163. break;
  164. case 'd':
  165. dflag=1;
  166. break;
  167. case 'D':
  168. dflag=1;
  169. longk=1;
  170. break;
  171. case 'b':
  172. bflag=1;
  173. break;
  174. case 'f':
  175. fflag=1;
  176. break;
  177. case 's':
  178. sflag=1;
  179. break;
  180. case 'u':
  181. uflag=1;
  182. strncpy(uuname,p,200);
  183. p+=strlen(uuname);
  184. break;
  185. case 'h':
  186. hflag=1;
  187. break;
  188. case 'k':
  189. kflag=1;
  190. if ((i+1) == argc)
  191. {
  192. fputs("must have a key with the -k option\n",stderr);
  193. error=1;
  194. }
  195. else
  196. {
  197. int j;
  198. i++;
  199. strncpy(key,argv[i],KEYSIZB);
  200. for (j=strlen(argv[i])-1; j>=0; j--)
  201. argv[i][j]='\0';
  202. }
  203. break;
  204. default:
  205. fprintf(stderr,"'%c' unknown flag\n",p[-1]);
  206. error=1;
  207. break;
  208. }
  209. }
  210. }
  211. else
  212. {
  213. if (in == NULL)
  214. in=argv[i];
  215. else if (out == NULL)
  216. out=argv[i];
  217. else
  218. error=1;
  219. }
  220. }
  221. if (error) usage();
  222. /* We either
  223. * do checksum or
  224. * do encrypt or
  225. * do decrypt or
  226. * do decrypt then ckecksum or
  227. * do checksum then encrypt
  228. */
  229. if (((eflag+dflag) == 1) || cflag)
  230. {
  231. if (eflag) do_encrypt=DES_ENCRYPT;
  232. if (dflag) do_encrypt=DES_DECRYPT;
  233. }
  234. else
  235. {
  236. if (vflag)
  237. {
  238. #ifndef _Windows
  239. fprintf(stderr,"des(1) built with %s\n",libdes_version);
  240. #endif
  241. EXIT(1);
  242. }
  243. else usage();
  244. }
  245. #ifndef _Windows
  246. if (vflag) fprintf(stderr,"des(1) built with %s\n",libdes_version);
  247. #endif
  248. if ( (in != NULL) &&
  249. (out != NULL) &&
  250. #ifndef OPENSSL_SYS_MSDOS
  251. (stat(in,&ins) != -1) &&
  252. (stat(out,&outs) != -1) &&
  253. (ins.st_dev == outs.st_dev) &&
  254. (ins.st_ino == outs.st_ino))
  255. #else /* OPENSSL_SYS_MSDOS */
  256. (strcmp(in,out) == 0))
  257. #endif
  258. {
  259. fputs("input and output file are the same\n",stderr);
  260. EXIT(3);
  261. }
  262. if (!kflag)
  263. if (des_read_pw_string(key,KEYSIZB+1,"Enter key:",eflag?VERIFY:0))
  264. {
  265. fputs("password error\n",stderr);
  266. EXIT(2);
  267. }
  268. if (in == NULL)
  269. DES_IN=stdin;
  270. else if ((DES_IN=fopen(in,"r")) == NULL)
  271. {
  272. perror("opening input file");
  273. EXIT(4);
  274. }
  275. CKSUM_OUT=stdout;
  276. if (out == NULL)
  277. {
  278. DES_OUT=stdout;
  279. CKSUM_OUT=stderr;
  280. }
  281. else if ((DES_OUT=fopen(out,"w")) == NULL)
  282. {
  283. perror("opening output file");
  284. EXIT(5);
  285. }
  286. #ifdef OPENSSL_SYS_MSDOS
  287. /* This should set the file to binary mode. */
  288. {
  289. #include <fcntl.h>
  290. if (!(uflag && dflag))
  291. setmode(fileno(DES_IN),O_BINARY);
  292. if (!(uflag && eflag))
  293. setmode(fileno(DES_OUT),O_BINARY);
  294. }
  295. #endif
  296. doencryption();
  297. fclose(DES_IN);
  298. fclose(DES_OUT);
  299. EXIT(0);
  300. }
  301. void usage(void)
  302. {
  303. char **u;
  304. static const char *Usage[]={
  305. "des <options> [input-file [output-file]]",
  306. "options:",
  307. "-v : des(1) version number",
  308. "-e : encrypt using SunOS compatible user key to DES key conversion.",
  309. "-E : encrypt ",
  310. "-d : decrypt using SunOS compatible user key to DES key conversion.",
  311. "-D : decrypt ",
  312. "-c[ckname] : generate a cbc_cksum using SunOS compatible user key to",
  313. " DES key conversion and output to ckname (stdout default,",
  314. " stderr if data being output on stdout). The checksum is",
  315. " generated before encryption and after decryption if used",
  316. " in conjunction with -[eEdD].",
  317. "-C[ckname] : generate a cbc_cksum as for -c but compatible with -[ED].",
  318. "-k key : use key 'key'",
  319. "-h : the key that is entered will be a hexadecimal number",
  320. " that is used directly as the des key",
  321. "-u[uuname] : input file is uudecoded if -[dD] or output uuencoded data if -[eE]",
  322. " (uuname is the filename to put in the uuencode header).",
  323. "-b : encrypt using DES in ecb encryption mode, the default is cbc mode.",
  324. "-3 : encrypt using triple DES encryption. This uses 2 keys",
  325. " generated from the input key. If the input key is less",
  326. " than 8 characters long, this is equivalent to normal",
  327. " encryption. Default is triple cbc, -b makes it triple ecb.",
  328. NULL
  329. };
  330. for (u=(char **)Usage; *u; u++)
  331. {
  332. fputs(*u,stderr);
  333. fputc('\n',stderr);
  334. }
  335. EXIT(1);
  336. }
  337. void doencryption(void)
  338. {
  339. #ifdef _LIBC
  340. extern unsigned long time();
  341. #endif
  342. register int i;
  343. des_key_schedule ks,ks2;
  344. des_cblock iv,iv2;
  345. char *p;
  346. int num=0,j,k,l,rem,ll,len,last,ex=0;
  347. des_cblock kk,k2;
  348. FILE *O;
  349. int Exit=0;
  350. #ifndef OPENSSL_SYS_MSDOS
  351. static unsigned char buf[BUFSIZE+8],obuf[BUFSIZE+8];
  352. #else
  353. static unsigned char *buf=NULL,*obuf=NULL;
  354. if (buf == NULL)
  355. {
  356. if ( (( buf=OPENSSL_malloc(BUFSIZE+8)) == NULL) ||
  357. ((obuf=OPENSSL_malloc(BUFSIZE+8)) == NULL))
  358. {
  359. fputs("Not enough memory\n",stderr);
  360. Exit=10;
  361. goto problems;
  362. }
  363. }
  364. #endif
  365. if (hflag)
  366. {
  367. j=(flag3?16:8);
  368. p=key;
  369. for (i=0; i<j; i++)
  370. {
  371. k=0;
  372. if ((*p <= '9') && (*p >= '0'))
  373. k=(*p-'0')<<4;
  374. else if ((*p <= 'f') && (*p >= 'a'))
  375. k=(*p-'a'+10)<<4;
  376. else if ((*p <= 'F') && (*p >= 'A'))
  377. k=(*p-'A'+10)<<4;
  378. else
  379. {
  380. fputs("Bad hex key\n",stderr);
  381. Exit=9;
  382. goto problems;
  383. }
  384. p++;
  385. if ((*p <= '9') && (*p >= '0'))
  386. k|=(*p-'0');
  387. else if ((*p <= 'f') && (*p >= 'a'))
  388. k|=(*p-'a'+10);
  389. else if ((*p <= 'F') && (*p >= 'A'))
  390. k|=(*p-'A'+10);
  391. else
  392. {
  393. fputs("Bad hex key\n",stderr);
  394. Exit=9;
  395. goto problems;
  396. }
  397. p++;
  398. if (i < 8)
  399. kk[i]=k;
  400. else
  401. k2[i-8]=k;
  402. }
  403. des_set_key_unchecked(&k2,ks2);
  404. memset(k2,0,sizeof(k2));
  405. }
  406. else if (longk || flag3)
  407. {
  408. if (flag3)
  409. {
  410. des_string_to_2keys(key,&kk,&k2);
  411. des_set_key_unchecked(&k2,ks2);
  412. memset(k2,0,sizeof(k2));
  413. }
  414. else
  415. des_string_to_key(key,&kk);
  416. }
  417. else
  418. for (i=0; i<KEYSIZ; i++)
  419. {
  420. l=0;
  421. k=key[i];
  422. for (j=0; j<8; j++)
  423. {
  424. if (k&1) l++;
  425. k>>=1;
  426. }
  427. if (l & 1)
  428. kk[i]=key[i]&0x7f;
  429. else
  430. kk[i]=key[i]|0x80;
  431. }
  432. des_set_key_unchecked(&kk,ks);
  433. memset(key,0,sizeof(key));
  434. memset(kk,0,sizeof(kk));
  435. /* woops - A bug that does not showup under unix :-( */
  436. memset(iv,0,sizeof(iv));
  437. memset(iv2,0,sizeof(iv2));
  438. l=1;
  439. rem=0;
  440. /* first read */
  441. if (eflag || (!dflag && cflag))
  442. {
  443. for (;;)
  444. {
  445. num=l=fread(&(buf[rem]),1,BUFSIZE,DES_IN);
  446. l+=rem;
  447. num+=rem;
  448. if (l < 0)
  449. {
  450. perror("read error");
  451. Exit=6;
  452. goto problems;
  453. }
  454. rem=l%8;
  455. len=l-rem;
  456. if (feof(DES_IN))
  457. {
  458. for (i=7-rem; i>0; i--)
  459. RAND_pseudo_bytes(buf + l++, 1);
  460. buf[l++]=rem;
  461. ex=1;
  462. len+=rem;
  463. }
  464. else
  465. l-=rem;
  466. if (cflag)
  467. {
  468. des_cbc_cksum(buf,&cksum,
  469. (long)len,ks,&cksum);
  470. if (!eflag)
  471. {
  472. if (feof(DES_IN)) break;
  473. else continue;
  474. }
  475. }
  476. if (bflag && !flag3)
  477. for (i=0; i<l; i+=8)
  478. des_ecb_encrypt(
  479. (des_cblock *)&(buf[i]),
  480. (des_cblock *)&(obuf[i]),
  481. ks,do_encrypt);
  482. else if (flag3 && bflag)
  483. for (i=0; i<l; i+=8)
  484. des_ecb2_encrypt(
  485. (des_cblock *)&(buf[i]),
  486. (des_cblock *)&(obuf[i]),
  487. ks,ks2,do_encrypt);
  488. else if (flag3 && !bflag)
  489. {
  490. char tmpbuf[8];
  491. if (rem) memcpy(tmpbuf,&(buf[l]),
  492. (unsigned int)rem);
  493. des_3cbc_encrypt(
  494. (des_cblock *)buf,(des_cblock *)obuf,
  495. (long)l,ks,ks2,&iv,
  496. &iv2,do_encrypt);
  497. if (rem) memcpy(&(buf[l]),tmpbuf,
  498. (unsigned int)rem);
  499. }
  500. else
  501. {
  502. des_cbc_encrypt(
  503. buf,obuf,
  504. (long)l,ks,&iv,do_encrypt);
  505. if (l >= 8) memcpy(iv,&(obuf[l-8]),8);
  506. }
  507. if (rem) memcpy(buf,&(buf[l]),(unsigned int)rem);
  508. i=0;
  509. while (i < l)
  510. {
  511. if (uflag)
  512. j=uufwrite(obuf,1,(unsigned int)l-i,
  513. DES_OUT);
  514. else
  515. j=fwrite(obuf,1,(unsigned int)l-i,
  516. DES_OUT);
  517. if (j == -1)
  518. {
  519. perror("Write error");
  520. Exit=7;
  521. goto problems;
  522. }
  523. i+=j;
  524. }
  525. if (feof(DES_IN))
  526. {
  527. if (uflag) uufwriteEnd(DES_OUT);
  528. break;
  529. }
  530. }
  531. }
  532. else /* decrypt */
  533. {
  534. ex=1;
  535. for (;;)
  536. {
  537. if (ex) {
  538. if (uflag)
  539. l=uufread(buf,1,BUFSIZE,DES_IN);
  540. else
  541. l=fread(buf,1,BUFSIZE,DES_IN);
  542. ex=0;
  543. rem=l%8;
  544. l-=rem;
  545. }
  546. if (l < 0)
  547. {
  548. perror("read error");
  549. Exit=6;
  550. goto problems;
  551. }
  552. if (bflag && !flag3)
  553. for (i=0; i<l; i+=8)
  554. des_ecb_encrypt(
  555. (des_cblock *)&(buf[i]),
  556. (des_cblock *)&(obuf[i]),
  557. ks,do_encrypt);
  558. else if (flag3 && bflag)
  559. for (i=0; i<l; i+=8)
  560. des_ecb2_encrypt(
  561. (des_cblock *)&(buf[i]),
  562. (des_cblock *)&(obuf[i]),
  563. ks,ks2,do_encrypt);
  564. else if (flag3 && !bflag)
  565. {
  566. des_3cbc_encrypt(
  567. (des_cblock *)buf,(des_cblock *)obuf,
  568. (long)l,ks,ks2,&iv,
  569. &iv2,do_encrypt);
  570. }
  571. else
  572. {
  573. des_cbc_encrypt(
  574. buf,obuf,
  575. (long)l,ks,&iv,do_encrypt);
  576. if (l >= 8) memcpy(iv,&(buf[l-8]),8);
  577. }
  578. if (uflag)
  579. ll=uufread(&(buf[rem]),1,BUFSIZE,DES_IN);
  580. else
  581. ll=fread(&(buf[rem]),1,BUFSIZE,DES_IN);
  582. ll+=rem;
  583. rem=ll%8;
  584. ll-=rem;
  585. if (feof(DES_IN) && (ll == 0))
  586. {
  587. last=obuf[l-1];
  588. if ((last > 7) || (last < 0))
  589. {
  590. fputs("The file was not decrypted correctly.\n",
  591. stderr);
  592. Exit=8;
  593. last=0;
  594. }
  595. l=l-8+last;
  596. }
  597. i=0;
  598. if (cflag) des_cbc_cksum(obuf,
  599. (des_cblock *)cksum,(long)l/8*8,ks,
  600. (des_cblock *)cksum);
  601. while (i != l)
  602. {
  603. j=fwrite(obuf,1,(unsigned int)l-i,DES_OUT);
  604. if (j == -1)
  605. {
  606. perror("Write error");
  607. Exit=7;
  608. goto problems;
  609. }
  610. i+=j;
  611. }
  612. l=ll;
  613. if ((l == 0) && feof(DES_IN)) break;
  614. }
  615. }
  616. if (cflag)
  617. {
  618. l=0;
  619. if (cksumname[0] != '\0')
  620. {
  621. if ((O=fopen(cksumname,"w")) != NULL)
  622. {
  623. CKSUM_OUT=O;
  624. l=1;
  625. }
  626. }
  627. for (i=0; i<8; i++)
  628. fprintf(CKSUM_OUT,"%02X",cksum[i]);
  629. fprintf(CKSUM_OUT,"\n");
  630. if (l) fclose(CKSUM_OUT);
  631. }
  632. problems:
  633. memset(buf,0,sizeof(buf));
  634. memset(obuf,0,sizeof(obuf));
  635. memset(ks,0,sizeof(ks));
  636. memset(ks2,0,sizeof(ks2));
  637. memset(iv,0,sizeof(iv));
  638. memset(iv2,0,sizeof(iv2));
  639. memset(kk,0,sizeof(kk));
  640. memset(k2,0,sizeof(k2));
  641. memset(uubuf,0,sizeof(uubuf));
  642. memset(b,0,sizeof(b));
  643. memset(bb,0,sizeof(bb));
  644. memset(cksum,0,sizeof(cksum));
  645. if (Exit) EXIT(Exit);
  646. }
  647. /* We ignore this parameter but it should be > ~50 I believe */
  648. int uufwrite(unsigned char *data, int size, unsigned int num, FILE *fp)
  649. {
  650. int i,j,left,rem,ret=num;
  651. static int start=1;
  652. if (start)
  653. {
  654. fprintf(fp,"begin 600 %s\n",
  655. (uuname[0] == '\0')?"text.d":uuname);
  656. start=0;
  657. }
  658. if (uubufnum)
  659. {
  660. if (uubufnum+num < 45)
  661. {
  662. memcpy(&(uubuf[uubufnum]),data,(unsigned int)num);
  663. uubufnum+=num;
  664. return(num);
  665. }
  666. else
  667. {
  668. i=45-uubufnum;
  669. memcpy(&(uubuf[uubufnum]),data,(unsigned int)i);
  670. j=uuencode((unsigned char *)uubuf,45,b);
  671. fwrite(b,1,(unsigned int)j,fp);
  672. uubufnum=0;
  673. data+=i;
  674. num-=i;
  675. }
  676. }
  677. for (i=0; i<(((int)num)-INUUBUFN); i+=INUUBUFN)
  678. {
  679. j=uuencode(&(data[i]),INUUBUFN,b);
  680. fwrite(b,1,(unsigned int)j,fp);
  681. }
  682. rem=(num-i)%45;
  683. left=(num-i-rem);
  684. if (left)
  685. {
  686. j=uuencode(&(data[i]),left,b);
  687. fwrite(b,1,(unsigned int)j,fp);
  688. i+=left;
  689. }
  690. if (i != num)
  691. {
  692. memcpy(uubuf,&(data[i]),(unsigned int)rem);
  693. uubufnum=rem;
  694. }
  695. return(ret);
  696. }
  697. void uufwriteEnd(FILE *fp)
  698. {
  699. int j;
  700. static const char *end=" \nend\n";
  701. if (uubufnum != 0)
  702. {
  703. uubuf[uubufnum]='\0';
  704. uubuf[uubufnum+1]='\0';
  705. uubuf[uubufnum+2]='\0';
  706. j=uuencode(uubuf,uubufnum,b);
  707. fwrite(b,1,(unsigned int)j,fp);
  708. }
  709. fwrite(end,1,strlen(end),fp);
  710. }
  711. /* int size: should always be > ~ 60; I actually ignore this parameter :-) */
  712. int uufread(unsigned char *out, int size, unsigned int num, FILE *fp)
  713. {
  714. int i,j,tot;
  715. static int done=0;
  716. static int valid=0;
  717. static int start=1;
  718. if (start)
  719. {
  720. for (;;)
  721. {
  722. b[0]='\0';
  723. fgets((char *)b,300,fp);
  724. if (b[0] == '\0')
  725. {
  726. fprintf(stderr,"no 'begin' found in uuencoded input\n");
  727. return(-1);
  728. }
  729. if (strncmp((char *)b,"begin ",6) == 0) break;
  730. }
  731. start=0;
  732. }
  733. if (done) return(0);
  734. tot=0;
  735. if (valid)
  736. {
  737. memcpy(out,bb,(unsigned int)valid);
  738. tot=valid;
  739. valid=0;
  740. }
  741. for (;;)
  742. {
  743. b[0]='\0';
  744. fgets((char *)b,300,fp);
  745. if (b[0] == '\0') break;
  746. i=strlen((char *)b);
  747. if ((b[0] == 'e') && (b[1] == 'n') && (b[2] == 'd'))
  748. {
  749. done=1;
  750. while (!feof(fp))
  751. {
  752. fgets((char *)b,300,fp);
  753. }
  754. break;
  755. }
  756. i=uudecode(b,i,bb);
  757. if (i < 0) break;
  758. if ((i+tot+8) > num)
  759. {
  760. /* num to copy to make it a multiple of 8 */
  761. j=(num/8*8)-tot-8;
  762. memcpy(&(out[tot]),bb,(unsigned int)j);
  763. tot+=j;
  764. memcpy(bb,&(bb[j]),(unsigned int)i-j);
  765. valid=i-j;
  766. break;
  767. }
  768. memcpy(&(out[tot]),bb,(unsigned int)i);
  769. tot+=i;
  770. }
  771. return(tot);
  772. }
  773. #define ccc2l(c,l) (l =((DES_LONG)(*((c)++)))<<16, \
  774. l|=((DES_LONG)(*((c)++)))<< 8, \
  775. l|=((DES_LONG)(*((c)++))))
  776. #define l2ccc(l,c) (*((c)++)=(unsigned char)(((l)>>16)&0xff), \
  777. *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
  778. *((c)++)=(unsigned char)(((l) )&0xff))
  779. int uuencode(unsigned char *in, int num, unsigned char *out)
  780. {
  781. int j,i,n,tot=0;
  782. DES_LONG l;
  783. register unsigned char *p;
  784. p=out;
  785. for (j=0; j<num; j+=45)
  786. {
  787. if (j+45 > num)
  788. i=(num-j);
  789. else i=45;
  790. *(p++)=i+' ';
  791. for (n=0; n<i; n+=3)
  792. {
  793. ccc2l(in,l);
  794. *(p++)=((l>>18)&0x3f)+' ';
  795. *(p++)=((l>>12)&0x3f)+' ';
  796. *(p++)=((l>> 6)&0x3f)+' ';
  797. *(p++)=((l )&0x3f)+' ';
  798. tot+=4;
  799. }
  800. *(p++)='\n';
  801. tot+=2;
  802. }
  803. *p='\0';
  804. l=0;
  805. return(tot);
  806. }
  807. int uudecode(unsigned char *in, int num, unsigned char *out)
  808. {
  809. int j,i,k;
  810. unsigned int n=0,space=0;
  811. DES_LONG l;
  812. DES_LONG w,x,y,z;
  813. unsigned int blank=(unsigned int)'\n'-' ';
  814. for (j=0; j<num; )
  815. {
  816. n= *(in++)-' ';
  817. if (n == blank)
  818. {
  819. n=0;
  820. in--;
  821. }
  822. if (n > 60)
  823. {
  824. fprintf(stderr,"uuencoded line length too long\n");
  825. return(-1);
  826. }
  827. j++;
  828. for (i=0; i<n; j+=4,i+=3)
  829. {
  830. /* the following is for cases where spaces are
  831. * removed from lines.
  832. */
  833. if (space)
  834. {
  835. w=x=y=z=0;
  836. }
  837. else
  838. {
  839. w= *(in++)-' ';
  840. x= *(in++)-' ';
  841. y= *(in++)-' ';
  842. z= *(in++)-' ';
  843. }
  844. if ((w > 63) || (x > 63) || (y > 63) || (z > 63))
  845. {
  846. k=0;
  847. if (w == blank) k=1;
  848. if (x == blank) k=2;
  849. if (y == blank) k=3;
  850. if (z == blank) k=4;
  851. space=1;
  852. switch (k) {
  853. case 1: w=0; in--;
  854. case 2: x=0; in--;
  855. case 3: y=0; in--;
  856. case 4: z=0; in--;
  857. break;
  858. case 0:
  859. space=0;
  860. fprintf(stderr,"bad uuencoded data values\n");
  861. w=x=y=z=0;
  862. return(-1);
  863. break;
  864. }
  865. }
  866. l=(w<<18)|(x<<12)|(y<< 6)|(z );
  867. l2ccc(l,out);
  868. }
  869. if (*(in++) != '\n')
  870. {
  871. fprintf(stderr,"missing nl in uuencoded line\n");
  872. w=x=y=z=0;
  873. return(-1);
  874. }
  875. j++;
  876. }
  877. *out='\0';
  878. w=x=y=z=0;
  879. return(n);
  880. }