15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* crypt.h -- base code for crypt/uncrypt ZIPfile
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   Version 1.01e, February 12th, 2005
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   Copyright (C) 1998-2005 Gilles Vollant
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   This code is a modified version of crypting code in Infozip distribution
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   The encryption/decryption parts of this source code (as opposed to the
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   non-echoing password parts) were originally written in Europe.  The
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   whole source package can be freely distributed, including from the USA.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   (Prior to January 2000, re-export from the US was a violation of US law.)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   This encryption code is a direct transcription of the algorithm from
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   file (appnote.txt) is distributed with the PKZIP program (even in the
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   version without encryption capabilities).
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   If you don't need crypting in your application, just define symbols
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   NOCRYPT and NOUNCRYPT.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   This code support the "Traditional PKWARE Encryption".
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   The new AES encryption added on Zip format by Winzip (see the page
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   Encryption is not supported.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/***********************************************************************
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Return the next byte in the pseudo-random sequence
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     * unpredictable manner on 16-bit systems; not a problem
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     * with any known compiler so far, though */
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/***********************************************************************
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Update the encryption keys with the next byte of plain text
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      register int keyshift = (int)((*(pkeys+1)) >> 24);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return c;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/***********************************************************************
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Initialize the encryption keys and the random header according to
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the given password.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(pkeys+0) = 305419896L;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(pkeys+1) = 591751049L;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(pkeys+2) = 878082192L;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (*passwd != '\0') {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        update_keys(pkeys,pcrc_32_tab,(int)*passwd);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        passwd++;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define zdecode(pkeys,pcrc_32_tab,c) \
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define zencode(pkeys,pcrc_32_tab,c,t) \
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RAND_HEAD_LEN  12
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   /* "last resort" source for second part of crypt seed pattern */
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  ifndef ZCR_SEED2
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#    define ZCR_SEED2 3141592654UL     /* use PI as default pattern */
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  endif
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int crypthead(const char* passwd,      /* password string */
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     unsigned char* buf,      /* where to write header */
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     int bufSize,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     unsigned long* pkeys,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const unsigned long* pcrc_32_tab,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     unsigned long crcForCrypting)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int n;                       /* index in random header */
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int t;                       /* temporary */
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int c;                       /* random byte */
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char header[RAND_HEAD_LEN-2]; /* random header */
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static unsigned calls = 0;   /* ensure different random header each time */
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (bufSize<RAND_HEAD_LEN)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 0;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * output of rand() to get less predictability, since rand() is
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * often poorly implemented.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (++calls == 1)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        srand((unsigned)(time(NULL) ^ ZCR_SEED2));
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    init_keys(passwd, pkeys, pcrc_32_tab);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (n = 0; n < RAND_HEAD_LEN-2; n++)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        c = (rand() >> 7) & 0xff;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Encrypt random header (last two bytes is high word of crc) */
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    init_keys(passwd, pkeys, pcrc_32_tab);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (n = 0; n < RAND_HEAD_LEN-2; n++)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return n;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
132