![]() |
Ignite Tools
|
00001 /* crypt.h -- base code for crypt/uncrypt ZIPfile 00002 00003 00004 Version 1.01e, February 12th, 2005 00005 00006 Copyright (C) 1998-2005 Gilles Vollant 00007 00008 This code is a modified version of crypting code in Infozip distribution 00009 00010 The encryption/decryption parts of this source code (as opposed to the 00011 non-echoing password parts) were originally written in Europe. The 00012 whole source package can be freely distributed, including from the USA. 00013 (Prior to January 2000, re-export from the US was a violation of US law.) 00014 00015 This encryption code is a direct transcription of the algorithm from 00016 Roger Schlafly, described by Phil Katz in the file appnote.txt. This 00017 file (appnote.txt) is distributed with the PKZIP program (even in the 00018 version without encryption capabilities). 00019 00020 If you don't need crypting in your application, just define symbols 00021 NOCRYPT and NOUNCRYPT. 00022 00023 This code support the "Traditional PKWARE Encryption". 00024 00025 The new AES encryption added on Zip format by Winzip (see the page 00026 http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong 00027 Encryption is not supported. 00028 */ 00029 00030 #define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) 00031 00032 /*********************************************************************** 00033 * Return the next byte in the pseudo-random sequence 00034 */ 00035 static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab) 00036 { 00037 unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an 00038 * unpredictable manner on 16-bit systems; not a problem 00039 * with any known compiler so far, though */ 00040 00041 temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; 00042 return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); 00043 } 00044 00045 /*********************************************************************** 00046 * Update the encryption keys with the next byte of plain text 00047 */ 00048 static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c) 00049 { 00050 (*(pkeys+0)) = CRC32((*(pkeys+0)), c); 00051 (*(pkeys+1)) += (*(pkeys+0)) & 0xff; 00052 (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; 00053 { 00054 register int keyshift = (int)((*(pkeys+1)) >> 24); 00055 (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); 00056 } 00057 return c; 00058 } 00059 00060 00061 /*********************************************************************** 00062 * Initialize the encryption keys and the random header according to 00063 * the given password. 00064 */ 00065 static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab) 00066 { 00067 *(pkeys+0) = 305419896L; 00068 *(pkeys+1) = 591751049L; 00069 *(pkeys+2) = 878082192L; 00070 while (*passwd != '\0') { 00071 update_keys(pkeys,pcrc_32_tab,(int)*passwd); 00072 passwd++; 00073 } 00074 } 00075 00076 #define zdecode(pkeys,pcrc_32_tab,c) \ 00077 (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) 00078 00079 #define zencode(pkeys,pcrc_32_tab,c,t) \ 00080 (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) 00081 00082 #ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED 00083 00084 #define RAND_HEAD_LEN 12 00085 /* "last resort" source for second part of crypt seed pattern */ 00086 # ifndef ZCR_SEED2 00087 # define ZCR_SEED2 3141592654UL /* use PI as default pattern */ 00088 # endif 00089 00090 static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting) 00091 const char *passwd; /* password string */ 00092 unsigned char *buf; /* where to write header */ 00093 int bufSize; 00094 unsigned long* pkeys; 00095 const unsigned long* pcrc_32_tab; 00096 unsigned long crcForCrypting; 00097 { 00098 int n; /* index in random header */ 00099 int t; /* temporary */ 00100 int c; /* random byte */ 00101 unsigned char header[RAND_HEAD_LEN-2]; /* random header */ 00102 static unsigned calls = 0; /* ensure different random header each time */ 00103 00104 if (bufSize<RAND_HEAD_LEN) 00105 return 0; 00106 00107 /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the 00108 * output of rand() to get less predictability, since rand() is 00109 * often poorly implemented. 00110 */ 00111 if (++calls == 1) 00112 { 00113 srand((unsigned)(time(NULL) ^ ZCR_SEED2)); 00114 } 00115 init_keys(passwd, pkeys, pcrc_32_tab); 00116 for (n = 0; n < RAND_HEAD_LEN-2; n++) 00117 { 00118 c = (rand() >> 7) & 0xff; 00119 header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); 00120 } 00121 /* Encrypt random header (last two bytes is high word of crc) */ 00122 init_keys(passwd, pkeys, pcrc_32_tab); 00123 for (n = 0; n < RAND_HEAD_LEN-2; n++) 00124 { 00125 buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); 00126 } 00127 buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); 00128 buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); 00129 return n; 00130 } 00131 00132 #endif