Home | History | Annotate | Line # | Download | only in minizip
crypt.h revision 1.1
      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  christos static int decrypt_byte(unsigned long* pkeys, const unsigned long* 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  christos     temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
     42  1.1  christos     return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
     43  1.1  christos }
     44  1.1  christos 
     45  1.1  christos /***********************************************************************
     46  1.1  christos  * Update the encryption keys with the next byte of plain text
     47  1.1  christos  */
     48  1.1  christos static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)
     49  1.1  christos {
     50  1.1  christos     (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
     51  1.1  christos     (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
     52  1.1  christos     (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
     53  1.1  christos     {
     54  1.1  christos       register int keyshift = (int)((*(pkeys+1)) >> 24);
     55  1.1  christos       (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
     56  1.1  christos     }
     57  1.1  christos     return c;
     58  1.1  christos }
     59  1.1  christos 
     60  1.1  christos 
     61  1.1  christos /***********************************************************************
     62  1.1  christos  * Initialize the encryption keys and the random header according to
     63  1.1  christos  * the given password.
     64  1.1  christos  */
     65  1.1  christos static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)
     66  1.1  christos {
     67  1.1  christos     *(pkeys+0) = 305419896L;
     68  1.1  christos     *(pkeys+1) = 591751049L;
     69  1.1  christos     *(pkeys+2) = 878082192L;
     70  1.1  christos     while (*passwd != '\0') {
     71  1.1  christos         update_keys(pkeys,pcrc_32_tab,(int)*passwd);
     72  1.1  christos         passwd++;
     73  1.1  christos     }
     74  1.1  christos }
     75  1.1  christos 
     76  1.1  christos #define zdecode(pkeys,pcrc_32_tab,c) \
     77  1.1  christos     (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
     78  1.1  christos 
     79  1.1  christos #define zencode(pkeys,pcrc_32_tab,c,t) \
     80  1.1  christos     (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
     81  1.1  christos 
     82  1.1  christos #ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
     83  1.1  christos 
     84  1.1  christos #define RAND_HEAD_LEN  12
     85  1.1  christos    /* "last resort" source for second part of crypt seed pattern */
     86  1.1  christos #  ifndef ZCR_SEED2
     87  1.1  christos #    define ZCR_SEED2 3141592654UL     /* use PI as default pattern */
     88  1.1  christos #  endif
     89  1.1  christos 
     90  1.1  christos static int crypthead(const char* passwd,      /* password string */
     91  1.1  christos                      unsigned char* buf,      /* where to write header */
     92  1.1  christos                      int bufSize,
     93  1.1  christos                      unsigned long* pkeys,
     94  1.1  christos                      const unsigned long* pcrc_32_tab,
     95  1.1  christos                      unsigned long crcForCrypting)
     96  1.1  christos {
     97  1.1  christos     int n;                       /* index in random header */
     98  1.1  christos     int t;                       /* temporary */
     99  1.1  christos     int c;                       /* random byte */
    100  1.1  christos     unsigned char header[RAND_HEAD_LEN-2]; /* random header */
    101  1.1  christos     static unsigned calls = 0;   /* ensure different random header each time */
    102  1.1  christos 
    103  1.1  christos     if (bufSize<RAND_HEAD_LEN)
    104  1.1  christos       return 0;
    105  1.1  christos 
    106  1.1  christos     /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
    107  1.1  christos      * output of rand() to get less predictability, since rand() is
    108  1.1  christos      * often poorly implemented.
    109  1.1  christos      */
    110  1.1  christos     if (++calls == 1)
    111  1.1  christos     {
    112  1.1  christos         srand((unsigned)(time(NULL) ^ ZCR_SEED2));
    113  1.1  christos     }
    114  1.1  christos     init_keys(passwd, pkeys, pcrc_32_tab);
    115  1.1  christos     for (n = 0; n < RAND_HEAD_LEN-2; n++)
    116  1.1  christos     {
    117  1.1  christos         c = (rand() >> 7) & 0xff;
    118  1.1  christos         header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
    119  1.1  christos     }
    120  1.1  christos     /* Encrypt random header (last two bytes is high word of crc) */
    121  1.1  christos     init_keys(passwd, pkeys, pcrc_32_tab);
    122  1.1  christos     for (n = 0; n < RAND_HEAD_LEN-2; n++)
    123  1.1  christos     {
    124  1.1  christos         buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
    125  1.1  christos     }
    126  1.1  christos     buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
    127  1.1  christos     buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
    128  1.1  christos     return n;
    129  1.1  christos }
    130  1.1  christos 
    131  1.1  christos #endif
    132