~ubuntu-branches/ubuntu/hardy/openssl/hardy-security

« back to all changes in this revision

Viewing changes to crypto/des/des.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Martin
  • Date: 2004-05-24 17:02:29 UTC
  • Revision ID: james.westby@ubuntu.com-20040524170229-ixlo08bbbly0xied
Tags: upstream-0.9.7d
ImportĀ upstreamĀ versionĀ 0.9.7d

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
        }