2
0

des.c 20 KB

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