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