/* crypt.h -- base code for crypt/uncrypt ZIPfile123Version 1.01e, February 12th, 200545Copyright (C) 1998-2005 Gilles Vollant67This code is a modified version of crypting code in Infozip distribution89The encryption/decryption parts of this source code (as opposed to the10non-echoing password parts) were originally written in Europe. The11whole source package can be freely distributed, including from the USA.12(Prior to January 2000, re-export from the US was a violation of US law.)1314This encryption code is a direct transcription of the algorithm from15Roger Schlafly, described by Phil Katz in the file appnote.txt. This16file (appnote.txt) is distributed with the PKZIP program (even in the17version without encryption capabilities).1819If you don't need crypting in your application, just define symbols20NOCRYPT and NOUNCRYPT.2122This code support the "Traditional PKWARE Encryption".2324The new AES encryption added on Zip format by Winzip (see the page25http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong26Encryption is not supported.27*/2829#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))3031/***********************************************************************32* Return the next byte in the pseudo-random sequence33*/34static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab) {35unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an36* unpredictable manner on 16-bit systems; not a problem37* with any known compiler so far, though */3839(void)pcrc_32_tab;40temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;41return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);42}4344/***********************************************************************45* Update the encryption keys with the next byte of plain text46*/47static int update_keys(unsigned long* pkeys, const z_crc_t* pcrc_32_tab, int c) {48(*(pkeys+0)) = CRC32((*(pkeys+0)), c);49(*(pkeys+1)) += (*(pkeys+0)) & 0xff;50(*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;51{52register int keyshift = (int)((*(pkeys+1)) >> 24);53(*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);54}55return c;56}575859/***********************************************************************60* Initialize the encryption keys and the random header according to61* the given password.62*/63static void init_keys(const char* passwd, unsigned long* pkeys, const z_crc_t* pcrc_32_tab) {64*(pkeys+0) = 305419896L;65*(pkeys+1) = 591751049L;66*(pkeys+2) = 878082192L;67while (*passwd != '\0') {68update_keys(pkeys,pcrc_32_tab,(int)*passwd);69passwd++;70}71}7273#define zdecode(pkeys,pcrc_32_tab,c) \74(update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))7576#define zencode(pkeys,pcrc_32_tab,c,t) \77(t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), (Byte)t^(c))7879#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED8081#define RAND_HEAD_LEN 1282/* "last resort" source for second part of crypt seed pattern */83# ifndef ZCR_SEED284# define ZCR_SEED2 3141592654UL /* use PI as default pattern */85# endif8687static unsigned crypthead(const char* passwd, /* password string */88unsigned char* buf, /* where to write header */89int bufSize,90unsigned long* pkeys,91const z_crc_t* pcrc_32_tab,92unsigned long crcForCrypting) {93unsigned n; /* index in random header */94int t; /* temporary */95int c; /* random byte */96unsigned char header[RAND_HEAD_LEN-2]; /* random header */97static unsigned calls = 0; /* ensure different random header each time */9899if (bufSize<RAND_HEAD_LEN)100return 0;101102/* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the103* output of rand() to get less predictability, since rand() is104* often poorly implemented.105*/106if (++calls == 1)107{108srand((unsigned)(time(NULL) ^ ZCR_SEED2));109}110init_keys(passwd, pkeys, pcrc_32_tab);111for (n = 0; n < RAND_HEAD_LEN-2; n++)112{113c = (rand() >> 7) & 0xff;114header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);115}116/* Encrypt random header (last two bytes is high word of crc) */117init_keys(passwd, pkeys, pcrc_32_tab);118for (n = 0; n < RAND_HEAD_LEN-2; n++)119{120buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);121}122buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);123buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);124return n;125}126127#endif128129130