File indexing completed on 2025-01-26 04:24:52

0001 /* crypt.h -- base code for crypt/uncrypt ZIPfile
0002 
0003 
0004    Version 1.01e, February 12th, 2005
0005 
0006    Copyright (C) 1998-2005 Gilles Vollant
0007 
0008    This code is a modified version of crypting code in Infozip distribution
0009 
0010    The encryption/decryption parts of this source code (as opposed to the
0011    non-echoing password parts) were originally written in Europe.  The
0012    whole source package can be freely distributed, including from the USA.
0013    (Prior to January 2000, re-export from the US was a violation of US law.)
0014 
0015    This encryption code is a direct transcription of the algorithm from
0016    Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
0017    file (appnote.txt) is distributed with the PKZIP program (even in the
0018    version without encryption capabilities).
0019 
0020    If you don't need crypting in your application, just define symbols
0021    NOCRYPT and NOUNCRYPT.
0022 
0023    This code support the "Traditional PKWARE Encryption".
0024 
0025    The new AES encryption added on Zip format by Winzip (see the page
0026    http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
0027    Encryption is not supported.
0028 */
0029 
0030 #include "quazip_global.h"
0031 
0032 #define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
0033 
0034 /***********************************************************************
0035  * Return the next byte in the pseudo-random sequence
0036  */
0037 static int decrypt_byte(unsigned long* pkeys, const z_crc_t FAR * pcrc_32_tab UNUSED)
0038 {
0039     //(void) pcrc_32_tab; /* avoid "unused parameter" warning */
0040     unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an
0041                      * unpredictable manner on 16-bit systems; not a problem
0042                      * with any known compiler so far, though */
0043 
0044     temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
0045     return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
0046 }
0047 
0048 /***********************************************************************
0049  * Update the encryption keys with the next byte of plain text
0050  */
0051 static int update_keys(unsigned long* pkeys,const z_crc_t FAR * pcrc_32_tab,int c)
0052 {
0053     (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
0054     (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
0055     (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
0056     {
0057       register int keyshift = (int)((*(pkeys+1)) >> 24);
0058       (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
0059     }
0060     return c;
0061 }
0062 
0063 
0064 /***********************************************************************
0065  * Initialize the encryption keys and the random header according to
0066  * the given password.
0067  */
0068 static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t FAR * pcrc_32_tab)
0069 {
0070     *(pkeys+0) = 305419896L;
0071     *(pkeys+1) = 591751049L;
0072     *(pkeys+2) = 878082192L;
0073     while (*passwd != '\0') {
0074         update_keys(pkeys,pcrc_32_tab,(int)*passwd);
0075         passwd++;
0076     }
0077 }
0078 
0079 #define zdecode(pkeys,pcrc_32_tab,c) \
0080     (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
0081 
0082 #define zencode(pkeys,pcrc_32_tab,c,t) \
0083     (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
0084 
0085 #ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
0086 
0087 #define RAND_HEAD_LEN  12
0088    /* "last resort" source for second part of crypt seed pattern */
0089 #  ifndef ZCR_SEED2
0090 #    define ZCR_SEED2 3141592654UL     /* use PI as default pattern */
0091 #  endif
0092 
0093 static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)
0094     const char *passwd;         /* password string */
0095     unsigned char *buf;         /* where to write header */
0096     int bufSize;
0097     unsigned long* pkeys;
0098     const z_crc_t FAR * pcrc_32_tab;
0099     unsigned long crcForCrypting;
0100 {
0101     int n;                       /* index in random header */
0102     int t;                       /* temporary */
0103     int c;                       /* random byte */
0104     unsigned char header[RAND_HEAD_LEN-2]; /* random header */
0105     static unsigned calls = 0;   /* ensure different random header each time */
0106 
0107     if (bufSize<RAND_HEAD_LEN)
0108       return 0;
0109 
0110     /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
0111      * output of rand() to get less predictability, since rand() is
0112      * often poorly implemented.
0113      */
0114     if (++calls == 1)
0115     {
0116         srand((unsigned)(time(NULL) ^ ZCR_SEED2));
0117     }
0118     init_keys(passwd, pkeys, pcrc_32_tab);
0119     for (n = 0; n < RAND_HEAD_LEN-2; n++)
0120     {
0121         c = (rand() >> 7) & 0xff;
0122         header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
0123     }
0124     /* Encrypt random header (last two bytes is high word of crc) */
0125     init_keys(passwd, pkeys, pcrc_32_tab);
0126     for (n = 0; n < RAND_HEAD_LEN-2; n++)
0127     {
0128         buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
0129     }
0130     buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
0131     buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
0132     return n;
0133 }
0134 
0135 #endif