1/*
2  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
3
4  See the accompanying file LICENSE, version 2000-Apr-09 or later
5  (the contents of which are also included in zip.h) for terms of use.
6  If, for some reason, all these files are missing, the Info-ZIP license
7  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
8*/
9/*
10  crypt.c (full version) by Info-ZIP.      Last revised:  [see crypt.h]
11
12  This encryption/decryption source code for Info-Zip software was
13  originally written in Europe.  The whole source package can be
14  freely distributed, including from the USA.  (Prior to January 2000,
15  re-export from the US was a violation of US law.)
16
17  NOTE on copyright history:
18  Previous versions of this source package (up to version 2.8) were
19  not copyrighted and put in the public domain.  If you cannot comply
20  with the Info-Zip LICENSE, you may want to look for one of those
21  public domain versions.
22 */
23
24/*
25  This encryption code is a direct transcription of the algorithm from
26  Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
27  file (appnote.txt) is distributed with the PKZIP program (even in the
28  version without encryption capabilities).
29 */
30
31#define ZCRYPT_INTERNAL
32#include "zip.h"
33#include "crypt.h"
34#include "ttyio.h"
35
36#if CRYPT
37
38#ifndef FALSE
39#  define FALSE 0
40#endif
41
42#ifdef ZIP
43   /* For the encoding task used in Zip (and ZipCloak), we want to initialize
44      the crypt algorithm with some reasonably unpredictable bytes, see
45      the crypthead() function. The standard rand() library function is
46      used to supply these `random' bytes, which in turn is initialized by
47      a srand() call. The srand() function takes an "unsigned" (at least 16bit)
48      seed value as argument to determine the starting point of the rand()
49      pseudo-random number generator.
50      This seed number is constructed as "Seed = Seed1 .XOR. Seed2" with
51      Seed1 supplied by the current time (= "(unsigned)time()") and Seed2
52      as some (hopefully) nondeterministic bitmask. On many (most) systems,
53      we use some "process specific" number, as the PID or something similar,
54      but when nothing unpredictable is available, a fixed number may be
55      sufficient.
56      NOTE:
57      1.) This implementation requires the availability of the following
58          standard UNIX C runtime library functions: time(), rand(), srand().
59          On systems where some of them are missing, the environment that
60          incorporates the crypt routines must supply suitable replacement
61          functions.
62      2.) It is a very bad idea to use a second call to time() to set the
63          "Seed2" number! In this case, both "Seed1" and "Seed2" would be
64          (almost) identical, resulting in a (mostly) "zero" constant seed
65          number passed to srand().
66
67      The implementation environment defined in the "zip.h" header should
68      supply a reasonable definition for ZCR_SEED2 (an unsigned number; for
69      most implementations of rand() and srand(), only the lower 16 bits are
70      significant!). An example that works on many systems would be
71           "#define ZCR_SEED2  (unsigned)getpid()".
72      The default definition for ZCR_SEED2 supplied below should be regarded
73      as a fallback to allow successful compilation in "beta state"
74      environments.
75    */
76#  include <time.h>     /* time() function supplies first part of crypt seed */
77   /* "last resort" source for second part of crypt seed pattern */
78#  ifndef ZCR_SEED2
79#    define ZCR_SEED2 (unsigned)3141592654L     /* use PI as default pattern */
80#  endif
81#  ifdef GLOBAL         /* used in Amiga system headers, maybe others too */
82#    undef GLOBAL
83#  endif
84#  define GLOBAL(g) g
85#else /* !ZIP */
86#  define GLOBAL(g) G.g
87#endif /* ?ZIP */
88
89
90#ifdef UNZIP
91   /* char *key = (char *)NULL; moved to globals.h */
92#  ifndef FUNZIP
93     local int testp OF((__GPRO__ ZCONST uch *h));
94     local int testkey OF((__GPRO__ ZCONST uch *h, ZCONST char *key));
95#  endif
96#endif /* UNZIP */
97
98#ifndef UNZIP             /* moved to globals.h for UnZip */
99   local ulg keys[3];     /* keys defining the pseudo-random sequence */
100#endif /* !UNZIP */
101
102#ifndef Trace
103#  ifdef CRYPT_DEBUG
104#    define Trace(x) fprintf x
105#  else
106#    define Trace(x)
107#  endif
108#endif
109
110#ifndef CRC_32_TAB
111#  define CRC_32_TAB     crc_32_tab
112#endif
113
114#define CRC32(c, b) (CRC_32_TAB[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
115
116/***********************************************************************
117 * Return the next byte in the pseudo-random sequence
118 */
119int decrypt_byte(__G)
120    __GDEF
121{
122    unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an
123                     * unpredictable manner on 16-bit systems; not a problem
124                     * with any known compiler so far, though */
125
126    temp = ((unsigned)GLOBAL(keys[2]) & 0xffff) | 2;
127    return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
128}
129
130/***********************************************************************
131 * Update the encryption keys with the next byte of plain text
132 */
133int update_keys(__G__ c)
134    __GDEF
135    int c;                      /* byte of plain text */
136{
137    GLOBAL(keys[0]) = CRC32(GLOBAL(keys[0]), c);
138    GLOBAL(keys[1]) += GLOBAL(keys[0]) & 0xff;
139    GLOBAL(keys[1]) = GLOBAL(keys[1]) * 134775813L + 1;
140    {
141      register int keyshift = (int)(GLOBAL(keys[1]) >> 24);
142      GLOBAL(keys[2]) = CRC32(GLOBAL(keys[2]), keyshift);
143    }
144    return c;
145}
146
147
148/***********************************************************************
149 * Initialize the encryption keys and the random header according to
150 * the given password.
151 */
152void init_keys(__G__ passwd)
153    __GDEF
154    ZCONST char *passwd;        /* password string with which to modify keys */
155{
156    GLOBAL(keys[0]) = 305419896L;
157    GLOBAL(keys[1]) = 591751049L;
158    GLOBAL(keys[2]) = 878082192L;
159    while (*passwd != '\0') {
160        update_keys(__G__ (int)*passwd);
161        passwd++;
162    }
163}
164
165
166#ifdef ZIP
167
168/***********************************************************************
169 * Write encryption header to file zfile using the password passwd
170 * and the cyclic redundancy check crc.
171 */
172void crypthead(passwd, crc, zfile)
173    ZCONST char *passwd;         /* password string */
174    ulg crc;                     /* crc of file being encrypted */
175    FILE *zfile;                 /* where to write header */
176{
177    int n;                       /* index in random header */
178    int t;                       /* temporary */
179    int c;                       /* random byte */
180    int ztemp;                   /* temporary for zencoded value */
181    uch header[RAND_HEAD_LEN-2]; /* random header */
182    static unsigned calls = 0;   /* ensure different random header each time */
183
184    /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
185     * output of rand() to get less predictability, since rand() is
186     * often poorly implemented.
187     */
188    if (++calls == 1) {
189        srand((unsigned)time(NULL) ^ ZCR_SEED2);
190    }
191    init_keys(passwd);
192    for (n = 0; n < RAND_HEAD_LEN-2; n++) {
193        c = (rand() >> 7) & 0xff;
194        header[n] = (uch)zencode(c, t);
195    }
196    /* Encrypt random header (last two bytes is high word of crc) */
197    init_keys(passwd);
198    for (n = 0; n < RAND_HEAD_LEN-2; n++) {
199        ztemp = zencode(header[n], t);
200        putc(ztemp, zfile);
201    }
202    ztemp = zencode((int)(crc >> 16) & 0xff, t);
203    putc(ztemp, zfile);
204    ztemp = zencode((int)(crc >> 24) & 0xff, t);
205    putc(ztemp, zfile);
206}
207
208
209#ifdef UTIL
210
211/***********************************************************************
212 * Encrypt the zip entry described by z from file source to file dest
213 * using the password passwd.  Return an error code in the ZE_ class.
214 */
215int zipcloak(z, source, dest, passwd)
216    struct zlist far *z;    /* zip entry to encrypt */
217    FILE *source, *dest;    /* source and destination files */
218    ZCONST char *passwd;    /* password string */
219{
220    int c;                  /* input byte */
221    int res;                /* result code */
222    ulg n;                  /* holds offset and counts size */
223    ush flag;               /* previous flags */
224    int t;                  /* temporary */
225    int ztemp;              /* temporary storage for zencode value */
226
227    /* Set encrypted bit, clear extended local header bit and write local
228       header to output file */
229    if ((n = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
230    z->off = n;
231    flag = z->flg;
232    z->flg |= 1,  z->flg &= ~8;
233    z->lflg |= 1, z->lflg &= ~8;
234    z->siz += RAND_HEAD_LEN;
235    if ((res = putlocal(z, dest)) != ZE_OK) return res;
236
237    /* Initialize keys with password and write random header */
238    crypthead(passwd, z->crc, dest);
239
240    /* Skip local header in input file */
241    if (fseek(source, (long)(4 + LOCHEAD + (ulg)z->nam + (ulg)z->ext),
242              SEEK_CUR)) {
243        return ferror(source) ? ZE_READ : ZE_EOF;
244    }
245
246    /* Encrypt data */
247    for (n = z->siz - RAND_HEAD_LEN; n; n--) {
248        if ((c = getc(source)) == EOF) {
249            return ferror(source) ? ZE_READ : ZE_EOF;
250        }
251        ztemp = zencode(c, t);
252        putc(ztemp, dest);
253    }
254    /* Skip extended local header in input file if there is one */
255    if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
256        return ferror(source) ? ZE_READ : ZE_EOF;
257    }
258    if (fflush(dest) == EOF) return ZE_TEMP;
259    return ZE_OK;
260}
261
262/***********************************************************************
263 * Decrypt the zip entry described by z from file source to file dest
264 * using the password passwd.  Return an error code in the ZE_ class.
265 */
266int zipbare(z, source, dest, passwd)
267    struct zlist far *z;  /* zip entry to encrypt */
268    FILE *source, *dest;  /* source and destination files */
269    ZCONST char *passwd;  /* password string */
270{
271    int c0, c1;           /* last two input bytes */
272    ulg offset;           /* used for file offsets */
273    ulg size;             /* size of input data */
274    int r;                /* size of encryption header */
275    int res;              /* return code */
276    ush flag;             /* previous flags */
277
278    /* Save position and skip local header in input file */
279    if ((offset = (ulg)ftell(source)) == (ulg)-1L ||
280        fseek(source, (long)(4 + LOCHEAD + (ulg)z->nam + (ulg)z->ext),
281              SEEK_CUR)) {
282        return ferror(source) ? ZE_READ : ZE_EOF;
283    }
284    /* Initialize keys with password */
285    init_keys(passwd);
286
287    /* Decrypt encryption header, save last two bytes */
288    c1 = 0;
289    for (r = RAND_HEAD_LEN; r; r--) {
290        c0 = c1;
291        if ((c1 = getc(source)) == EOF) {
292            return ferror(source) ? ZE_READ : ZE_EOF;
293        }
294        Trace((stdout, " (%02x)", c1));
295        zdecode(c1);
296        Trace((stdout, " %02x", c1));
297    }
298    Trace((stdout, "\n"));
299
300    /* If last two bytes of header don't match crc (or file time in the
301     * case of an extended local header), back up and just copy. For
302     * pkzip 2.0, the check has been reduced to one byte only.
303     */
304#ifdef ZIP10
305    if ((ush)(c0 | (c1<<8)) !=
306        (z->flg & 8 ? (ush) z->tim & 0xffff : (ush)(z->crc >> 16))) {
307#else
308    c0++; /* avoid warning on unused variable */
309    if ((ush)c1 != (z->flg & 8 ? (ush) z->tim >> 8 : (ush)(z->crc >> 24))) {
310#endif
311        if (fseek(source, offset, SEEK_SET)) {
312            return ferror(source) ? ZE_READ : ZE_EOF;
313        }
314        if ((res = zipcopy(z, source, dest)) != ZE_OK) return res;
315        return ZE_MISS;
316    }
317
318    /* Clear encrypted bit and local header bit, and write local header to
319       output file */
320    if ((offset = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
321    z->off = offset;
322    flag = z->flg;
323    z->flg &= ~9;
324    z->lflg &= ~9;
325    z->siz -= RAND_HEAD_LEN;
326    if ((res = putlocal(z, dest)) != ZE_OK) return res;
327
328    /* Decrypt data */
329    for (size = z->siz; size; size--) {
330        if ((c1 = getc(source)) == EOF) {
331            return ferror(source) ? ZE_READ : ZE_EOF;
332        }
333        zdecode(c1);
334        putc(c1, dest);
335    }
336    /* Skip extended local header in input file if there is one */
337    if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
338        return ferror(source) ? ZE_READ : ZE_EOF;
339    }
340    if (fflush(dest) == EOF) return ZE_TEMP;
341
342    return ZE_OK;
343}
344
345
346#else /* !UTIL */
347
348/***********************************************************************
349 * If requested, encrypt the data in buf, and in any case call fwrite()
350 * with the arguments to zfwrite().  Return what fwrite() returns.
351 */
352unsigned zfwrite(buf, item_size, nb, f)
353    zvoid *buf;                 /* data buffer */
354    extent item_size;           /* size of each item in bytes */
355    extent nb;                  /* number of items */
356    FILE *f;                    /* file to write to */
357{
358    int t;                      /* temporary */
359
360    if (key != (char *)NULL) {  /* key is the global password pointer */
361        ulg size;               /* buffer size */
362        char *p = (char*)buf;   /* steps through buffer */
363
364        /* Encrypt data in buffer */
365        for (size = item_size*(ulg)nb; size != 0; p++, size--) {
366            *p = (char)zencode(*p, t);
367        }
368    }
369    /* Write the buffer out */
370    return fwrite(buf, item_size, nb, f);
371}
372
373#endif /* ?UTIL */
374#endif /* ZIP */
375
376
377#if (defined(UNZIP) && !defined(FUNZIP))
378
379/***********************************************************************
380 * Get the password and set up keys for current zipfile member.
381 * Return PK_ class error.
382 */
383int decrypt(__G__ passwrd)
384    __GDEF
385    ZCONST char *passwrd;
386{
387    ush b;
388    int n, r;
389    uch h[RAND_HEAD_LEN];
390
391    Trace((stdout, "\n[incnt = %d]: ", GLOBAL(incnt)));
392
393    /* get header once (turn off "encrypted" flag temporarily so we don't
394     * try to decrypt the same data twice) */
395    GLOBAL(pInfo->encrypted) = FALSE;
396    defer_leftover_input(__G);
397    for (n = 0; n < RAND_HEAD_LEN; n++) {
398        b = NEXTBYTE;
399        h[n] = (uch)b;
400        Trace((stdout, " (%02x)", h[n]));
401    }
402    undefer_input(__G);
403    GLOBAL(pInfo->encrypted) = TRUE;
404
405    if (GLOBAL(newzip)) { /* this is first encrypted member in this zipfile */
406        GLOBAL(newzip) = FALSE;
407        if (passwrd != (char *)NULL) { /* user gave password on command line */
408            if (!GLOBAL(key)) {
409                if ((GLOBAL(key) = (char *)malloc(strlen(passwrd)+1)) ==
410                    (char *)NULL)
411                    return PK_MEM2;
412                strcpy(GLOBAL(key), passwrd);
413                GLOBAL(nopwd) = TRUE;  /* inhibit password prompting! */
414            }
415        } else if (GLOBAL(key)) { /* get rid of previous zipfile's key */
416            free(GLOBAL(key));
417            GLOBAL(key) = (char *)NULL;
418        }
419    }
420
421    /* if have key already, test it; else allocate memory for it */
422    if (GLOBAL(key)) {
423        if (!testp(__G__ h))
424            return PK_COOL;   /* existing password OK (else prompt for new) */
425        else if (GLOBAL(nopwd))
426            return PK_WARN;   /* user indicated no more prompting */
427    } else if ((GLOBAL(key) = (char *)malloc(IZ_PWLEN+1)) == (char *)NULL)
428        return PK_MEM2;
429
430    /* try a few keys */
431    n = 0;
432    do {
433        r = (*G.decr_passwd)((zvoid *)&G, &n, GLOBAL(key), IZ_PWLEN+1,
434                             GLOBAL(zipfn), GLOBAL(filename));
435        if (r == IZ_PW_ERROR) {         /* internal error in fetch of PW */
436            free (GLOBAL(key));
437            GLOBAL(key) = NULL;
438            return PK_MEM2;
439        }
440        if (r != IZ_PW_ENTERED) {       /* user replied "skip" or "skip all" */
441            *GLOBAL(key) = '\0';        /*   We try the NIL password, ... */
442            n = 0;                      /*   and cancel fetch for this item. */
443        }
444        if (!testp(__G__ h))
445            return PK_COOL;
446        if (r == IZ_PW_CANCELALL)       /* User replied "Skip all" */
447            GLOBAL(nopwd) = TRUE;       /*   inhibit any further PW prompt! */
448    } while (n > 0);
449
450    return PK_WARN;
451
452} /* end function decrypt() */
453
454
455
456/***********************************************************************
457 * Test the password.  Return -1 if bad, 0 if OK.
458 */
459local int testp(__G__ h)
460    __GDEF
461    ZCONST uch *h;
462{
463    int r;
464    char *key_translated;
465
466    /* On systems with "obscure" native character coding (e.g., EBCDIC),
467     * the first test translates the password to the "main standard"
468     * character coding. */
469
470#ifdef STR_TO_CP1
471    /* allocate buffer for translated password */
472    if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL)
473        return -1;
474    /* first try, test password translated "standard" charset */
475    r = testkey(__G__ h, STR_TO_CP1(key_translated, GLOBAL(key)));
476#else /* !STR_TO_CP1 */
477    /* first try, test password as supplied on the extractor's host */
478    r = testkey(__G__ h, GLOBAL(key));
479#endif /* ?STR_TO_CP1 */
480
481#ifdef STR_TO_CP2
482    if (r != 0) {
483#ifndef STR_TO_CP1
484        /* now prepare for second (and maybe third) test with translated pwd */
485        if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL)
486            return -1;
487#endif
488        /* second try, password translated to alternate ("standard") charset */
489        r = testkey(__G__ h, STR_TO_CP2(key_translated, GLOBAL(key)));
490#ifdef STR_TO_CP3
491        if (r != 0)
492            /* third try, password translated to another "standard" charset */
493            r = testkey(__G__ h, STR_TO_CP3(key_translated, GLOBAL(key)));
494#endif
495#ifndef STR_TO_CP1
496        free(key_translated);
497#endif
498    }
499#endif /* STR_TO_CP2 */
500
501#ifdef STR_TO_CP1
502    free(key_translated);
503    if (r != 0) {
504        /* last resort, test password as supplied on the extractor's host */
505        r = testkey(__G__ h, GLOBAL(key));
506    }
507#endif /* STR_TO_CP1 */
508
509    return r;
510
511} /* end function testp() */
512
513
514local int testkey(__G__ h, key)
515    __GDEF
516    ZCONST uch *h;      /* decrypted header */
517    ZCONST char *key;   /* decryption password to test */
518{
519    ush b;
520#ifdef ZIP10
521    ush c;
522#endif
523    int n;
524    uch *p;
525    uch hh[RAND_HEAD_LEN]; /* decrypted header */
526
527    /* set keys and save the encrypted header */
528    init_keys(__G__ key);
529    memcpy(hh, h, RAND_HEAD_LEN);
530
531    /* check password */
532    for (n = 0; n < RAND_HEAD_LEN; n++) {
533        zdecode(hh[n]);
534        Trace((stdout, " %02x", hh[n]));
535    }
536
537    Trace((stdout,
538      "\n  lrec.crc= %08lx  crec.crc= %08lx  pInfo->ExtLocHdr= %s\n",
539      GLOBAL(lrec.crc32), GLOBAL(pInfo->crc),
540      GLOBAL(pInfo->ExtLocHdr) ? "true":"false"));
541    Trace((stdout, "  incnt = %d  unzip offset into zipfile = %ld\n",
542      GLOBAL(incnt),
543      GLOBAL(cur_zipfile_bufstart)+(GLOBAL(inptr)-GLOBAL(inbuf))));
544
545    /* same test as in zipbare(): */
546
547#ifdef ZIP10 /* check two bytes */
548    c = hh[RAND_HEAD_LEN-2], b = hh[RAND_HEAD_LEN-1];
549    Trace((stdout,
550      "  (c | (b<<8)) = %04x  (crc >> 16) = %04x  lrec.time = %04x\n",
551      (ush)(c | (b<<8)), (ush)(GLOBAL(lrec.crc32) >> 16),
552      ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff))));
553    if ((ush)(c | (b<<8)) != (GLOBAL(pInfo->ExtLocHdr) ?
554                           ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff) :
555                           (ush)(GLOBAL(lrec.crc32) >> 16)))
556        return -1;  /* bad */
557#else
558    b = hh[RAND_HEAD_LEN-1];
559    Trace((stdout, "  b = %02x  (crc >> 24) = %02x  (lrec.time >> 8) = %02x\n",
560      b, (ush)(GLOBAL(lrec.crc32) >> 24),
561      ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff));
562    if (b != (GLOBAL(pInfo->ExtLocHdr) ?
563        ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff :
564        (ush)(GLOBAL(lrec.crc32) >> 24)))
565        return -1;  /* bad */
566#endif
567    /* password OK:  decrypt current buffer contents before leaving */
568    for (n = (long)GLOBAL(incnt) > GLOBAL(csize) ?
569             (int)GLOBAL(csize) : GLOBAL(incnt),
570         p = GLOBAL(inptr); n--; p++)
571        zdecode(*p);
572    return 0;       /* OK */
573
574} /* end function testkey() */
575
576#endif /* UNZIP && !FUNZIP */
577
578#else /* !CRYPT */
579
580/* something "externally visible" to shut up compiler/linker warnings */
581int zcr_dummy;
582
583#endif /* ?CRYPT */
584