kusano fc6ab3
/* crypt.h -- base code for crypt/uncrypt ZIPfile
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
   Version 1.01e, February 12th, 2005
kusano fc6ab3
kusano fc6ab3
   Copyright (C) 1998-2005 Gilles Vollant
kusano fc6ab3
kusano fc6ab3
   This code is a modified version of crypting code in Infozip distribution
kusano fc6ab3
kusano fc6ab3
   The encryption/decryption parts of this source code (as opposed to the
kusano fc6ab3
   non-echoing password parts) were originally written in Europe.  The
kusano fc6ab3
   whole source package can be freely distributed, including from the USA.
kusano fc6ab3
   (Prior to January 2000, re-export from the US was a violation of US law.)
kusano fc6ab3
kusano fc6ab3
   This encryption code is a direct transcription of the algorithm from
kusano fc6ab3
   Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
kusano fc6ab3
   file (appnote.txt) is distributed with the PKZIP program (even in the
kusano fc6ab3
   version without encryption capabilities).
kusano fc6ab3
kusano fc6ab3
   If you don't need crypting in your application, just define symbols
kusano fc6ab3
   NOCRYPT and NOUNCRYPT.
kusano fc6ab3
kusano fc6ab3
   This code support the "Traditional PKWARE Encryption".
kusano fc6ab3
kusano fc6ab3
   The new AES encryption added on Zip format by Winzip (see the page
kusano fc6ab3
   http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
kusano fc6ab3
   Encryption is not supported.
kusano fc6ab3
*/
kusano fc6ab3
kusano fc6ab3
#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
kusano fc6ab3
kusano fc6ab3
/***********************************************************************
kusano fc6ab3
 * Return the next byte in the pseudo-random sequence
kusano fc6ab3
 */
kusano fc6ab3
static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab)
kusano fc6ab3
{
kusano fc6ab3
    unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an
kusano fc6ab3
                     * unpredictable manner on 16-bit systems; not a problem
kusano fc6ab3
                     * with any known compiler so far, though */
kusano fc6ab3
kusano fc6ab3
    temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
kusano fc6ab3
    return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
/***********************************************************************
kusano fc6ab3
 * Update the encryption keys with the next byte of plain text
kusano fc6ab3
 */
kusano fc6ab3
static int update_keys(unsigned long* pkeys,const z_crc_t* pcrc_32_tab,int c)
kusano fc6ab3
{
kusano fc6ab3
    (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
kusano fc6ab3
    (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
kusano fc6ab3
    (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
kusano fc6ab3
    {
kusano fc6ab3
      register int keyshift = (int)((*(pkeys+1)) >> 24);
kusano fc6ab3
      (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
kusano fc6ab3
    }
kusano fc6ab3
    return c;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
/***********************************************************************
kusano fc6ab3
 * Initialize the encryption keys and the random header according to
kusano fc6ab3
 * the given password.
kusano fc6ab3
 */
kusano fc6ab3
static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t* pcrc_32_tab)
kusano fc6ab3
{
kusano fc6ab3
    *(pkeys+0) = 305419896L;
kusano fc6ab3
    *(pkeys+1) = 591751049L;
kusano fc6ab3
    *(pkeys+2) = 878082192L;
kusano fc6ab3
    while (*passwd != '\0') {
kusano fc6ab3
        update_keys(pkeys,pcrc_32_tab,(int)*passwd);
kusano fc6ab3
        passwd++;
kusano fc6ab3
    }
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
#define zdecode(pkeys,pcrc_32_tab,c) \
kusano fc6ab3
    (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
kusano fc6ab3
kusano fc6ab3
#define zencode(pkeys,pcrc_32_tab,c,t) \
kusano fc6ab3
    (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
kusano fc6ab3
kusano fc6ab3
#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
kusano fc6ab3
kusano fc6ab3
#define RAND_HEAD_LEN  12
kusano fc6ab3
   /* "last resort" source for second part of crypt seed pattern */
kusano fc6ab3
#  ifndef ZCR_SEED2
kusano fc6ab3
#    define ZCR_SEED2 3141592654UL     /* use PI as default pattern */
kusano fc6ab3
#  endif
kusano fc6ab3
kusano fc6ab3
static int crypthead(const char* passwd,      /* password string */
kusano fc6ab3
                     unsigned char* buf,      /* where to write header */
kusano fc6ab3
                     int bufSize,
kusano fc6ab3
                     unsigned long* pkeys,
kusano fc6ab3
                     const z_crc_t* pcrc_32_tab,
kusano fc6ab3
                     unsigned long crcForCrypting)
kusano fc6ab3
{
kusano fc6ab3
    int n;                       /* index in random header */
kusano fc6ab3
    int t;                       /* temporary */
kusano fc6ab3
    int c;                       /* random byte */
kusano fc6ab3
    unsigned char header[RAND_HEAD_LEN-2]; /* random header */
kusano fc6ab3
    static unsigned calls = 0;   /* ensure different random header each time */
kusano fc6ab3
kusano fc6ab3
    if (bufSize
kusano fc6ab3
      return 0;
kusano fc6ab3
kusano fc6ab3
    /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
kusano fc6ab3
     * output of rand() to get less predictability, since rand() is
kusano fc6ab3
     * often poorly implemented.
kusano fc6ab3
     */
kusano fc6ab3
    if (++calls == 1)
kusano fc6ab3
    {
kusano fc6ab3
        srand((unsigned)(time(NULL) ^ ZCR_SEED2));
kusano fc6ab3
    }
kusano fc6ab3
    init_keys(passwd, pkeys, pcrc_32_tab);
kusano fc6ab3
    for (n = 0; n < RAND_HEAD_LEN-2; n++)
kusano fc6ab3
    {
kusano fc6ab3
        c = (rand() >> 7) & 0xff;
kusano fc6ab3
        header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
kusano fc6ab3
    }
kusano fc6ab3
    /* Encrypt random header (last two bytes is high word of crc) */
kusano fc6ab3
    init_keys(passwd, pkeys, pcrc_32_tab);
kusano fc6ab3
    for (n = 0; n < RAND_HEAD_LEN-2; n++)
kusano fc6ab3
    {
kusano fc6ab3
        buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
kusano fc6ab3
    }
kusano fc6ab3
    buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
kusano fc6ab3
    buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
kusano fc6ab3
    return n;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
#endif