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