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