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