Home | History | Annotate | Line # | Download | only in minizip
      1      1.1  christos /* crypt.h -- base code for crypt/uncrypt ZIPfile
      2      1.1  christos 
      3      1.1  christos 
      4      1.1  christos    Version 1.01e, February 12th, 2005
      5      1.1  christos 
      6      1.1  christos    Copyright (C) 1998-2005 Gilles Vollant
      7      1.1  christos 
      8      1.1  christos    This code is a modified version of crypting code in Infozip distribution
      9      1.1  christos 
     10      1.1  christos    The encryption/decryption parts of this source code (as opposed to the
     11      1.1  christos    non-echoing password parts) were originally written in Europe.  The
     12      1.1  christos    whole source package can be freely distributed, including from the USA.
     13      1.1  christos    (Prior to January 2000, re-export from the US was a violation of US law.)
     14      1.1  christos 
     15      1.1  christos    This encryption code is a direct transcription of the algorithm from
     16      1.1  christos    Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
     17      1.1  christos    file (appnote.txt) is distributed with the PKZIP program (even in the
     18      1.1  christos    version without encryption capabilities).
     19      1.1  christos 
     20      1.1  christos    If you don't need crypting in your application, just define symbols
     21      1.1  christos    NOCRYPT and NOUNCRYPT.
     22      1.1  christos 
     23      1.1  christos    This code support the "Traditional PKWARE Encryption".
     24      1.1  christos 
     25      1.1  christos    The new AES encryption added on Zip format by Winzip (see the page
     26      1.1  christos    http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
     27      1.1  christos    Encryption is not supported.
     28      1.1  christos */
     29      1.1  christos 
     30      1.1  christos #define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
     31      1.1  christos 
     32      1.1  christos /***********************************************************************
     33      1.1  christos  * Return the next byte in the pseudo-random sequence
     34      1.1  christos  */
     35  1.1.1.2  christos static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab)
     36      1.1  christos {
     37      1.1  christos     unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an
     38      1.1  christos                      * unpredictable manner on 16-bit systems; not a problem
     39      1.1  christos                      * with any known compiler so far, though */
     40      1.1  christos 
     41  1.1.1.3  christos     (void)pcrc_32_tab;
     42      1.1  christos     temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
     43      1.1  christos     return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
     44      1.1  christos }
     45      1.1  christos 
     46      1.1  christos /***********************************************************************
     47      1.1  christos  * Update the encryption keys with the next byte of plain text
     48      1.1  christos  */
     49  1.1.1.2  christos static int update_keys(unsigned long* pkeys,const z_crc_t* pcrc_32_tab,int c)
     50      1.1  christos {
     51      1.1  christos     (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
     52      1.1  christos     (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
     53      1.1  christos     (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
     54      1.1  christos     {
     55      1.1  christos       register int keyshift = (int)((*(pkeys+1)) >> 24);
     56      1.1  christos       (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
     57      1.1  christos     }
     58      1.1  christos     return c;
     59      1.1  christos }
     60      1.1  christos 
     61      1.1  christos 
     62      1.1  christos /***********************************************************************
     63      1.1  christos  * Initialize the encryption keys and the random header according to
     64      1.1  christos  * the given password.
     65      1.1  christos  */
     66  1.1.1.2  christos static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t* pcrc_32_tab)
     67      1.1  christos {
     68      1.1  christos     *(pkeys+0) = 305419896L;
     69      1.1  christos     *(pkeys+1) = 591751049L;
     70      1.1  christos     *(pkeys+2) = 878082192L;
     71      1.1  christos     while (*passwd != '\0') {
     72      1.1  christos         update_keys(pkeys,pcrc_32_tab,(int)*passwd);
     73      1.1  christos         passwd++;
     74      1.1  christos     }
     75      1.1  christos }
     76      1.1  christos 
     77      1.1  christos #define zdecode(pkeys,pcrc_32_tab,c) \
     78      1.1  christos     (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
     79      1.1  christos 
     80      1.1  christos #define zencode(pkeys,pcrc_32_tab,c,t) \
     81  1.1.1.3  christos     (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), (Byte)t^(c))
     82      1.1  christos 
     83      1.1  christos #ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
     84      1.1  christos 
     85      1.1  christos #define RAND_HEAD_LEN  12
     86      1.1  christos    /* "last resort" source for second part of crypt seed pattern */
     87      1.1  christos #  ifndef ZCR_SEED2
     88  1.1.1.3  christos #    define ZCR_SEED2 3141592654L       /* use PI as default pattern */
     89      1.1  christos #  endif
     90      1.1  christos 
     91  1.1.1.3  christos static unsigned crypthead(const char* passwd,       /* password string */
     92  1.1.1.3  christos                           unsigned char* buf,       /* where to write header */
     93  1.1.1.3  christos                           int bufSize,
     94  1.1.1.3  christos                           unsigned long* pkeys,
     95  1.1.1.3  christos                           const z_crc_t* pcrc_32_tab,
     96  1.1.1.3  christos                           unsigned long crcForCrypting)
     97      1.1  christos {
     98  1.1.1.3  christos     unsigned n;                  /* index in random header */
     99      1.1  christos     int t;                       /* temporary */
    100      1.1  christos     int c;                       /* random byte */
    101      1.1  christos     unsigned char header[RAND_HEAD_LEN-2]; /* random header */
    102      1.1  christos     static unsigned calls = 0;   /* ensure different random header each time */
    103      1.1  christos 
    104      1.1  christos     if (bufSize<RAND_HEAD_LEN)
    105      1.1  christos       return 0;
    106      1.1  christos 
    107      1.1  christos     /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
    108      1.1  christos      * output of rand() to get less predictability, since rand() is
    109      1.1  christos      * often poorly implemented.
    110      1.1  christos      */
    111      1.1  christos     if (++calls == 1)
    112      1.1  christos     {
    113      1.1  christos         srand((unsigned)(time(NULL) ^ ZCR_SEED2));
    114      1.1  christos     }
    115      1.1  christos     init_keys(passwd, pkeys, pcrc_32_tab);
    116      1.1  christos     for (n = 0; n < RAND_HEAD_LEN-2; n++)
    117      1.1  christos     {
    118      1.1  christos         c = (rand() >> 7) & 0xff;
    119      1.1  christos         header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
    120      1.1  christos     }
    121      1.1  christos     /* Encrypt random header (last two bytes is high word of crc) */
    122      1.1  christos     init_keys(passwd, pkeys, pcrc_32_tab);
    123      1.1  christos     for (n = 0; n < RAND_HEAD_LEN-2; n++)
    124      1.1  christos     {
    125      1.1  christos         buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
    126      1.1  christos     }
    127      1.1  christos     buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
    128      1.1  christos     buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
    129      1.1  christos     return n;
    130      1.1  christos }
    131      1.1  christos 
    132      1.1  christos #endif
    133