5752
+ − 1
/* crypt.h -- base code for crypt/uncrypt ZIPfile
+ − 2
+ − 3
+ − 4
Version 1.01e, February 12th, 2005
+ − 5
+ − 6
Copyright (C) 1998-2005 Gilles Vollant
+ − 7
+ − 8
This code is a modified version of crypting code in Infozip distribution
+ − 9
+ − 10
The encryption/decryption parts of this source code (as opposed to the
+ − 11
non-echoing password parts) were originally written in Europe. The
+ − 12
whole source package can be freely distributed, including from the USA.
+ − 13
(Prior to January 2000, re-export from the US was a violation of US law.)
+ − 14
+ − 15
This encryption code is a direct transcription of the algorithm from
+ − 16
Roger Schlafly, described by Phil Katz in the file appnote.txt. This
+ − 17
file (appnote.txt) is distributed with the PKZIP program (even in the
+ − 18
version without encryption capabilities).
+ − 19
+ − 20
If you don't need crypting in your application, just define symbols
+ − 21
NOCRYPT and NOUNCRYPT.
+ − 22
+ − 23
This code support the "Traditional PKWARE Encryption".
+ − 24
+ − 25
The new AES encryption added on Zip format by Winzip (see the page
+ − 26
http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
+ − 27
Encryption is not supported.
+ − 28
*/
+ − 29
+ − 30
#include "quazip_global.h"
+ − 31
+ − 32
#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
+ − 33
+ − 34
/***********************************************************************
+ − 35
* Return the next byte in the pseudo-random sequence
+ − 36
*/
+ − 37
static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab UNUSED)
+ − 38
{
+ − 39
//(void) pcrc_32_tab; /* avoid "unused parameter" warning */
+ − 40
unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
+ − 41
* unpredictable manner on 16-bit systems; not a problem
+ − 42
* with any known compiler so far, though */
+ − 43
+ − 44
temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
+ − 45
return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
+ − 46
}
+ − 47
+ − 48
/***********************************************************************
+ − 49
* Update the encryption keys with the next byte of plain text
+ − 50
*/
+ − 51
static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)
+ − 52
{
+ − 53
(*(pkeys+0)) = CRC32((*(pkeys+0)), c);
+ − 54
(*(pkeys+1)) += (*(pkeys+0)) & 0xff;
+ − 55
(*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
+ − 56
{
+ − 57
register int keyshift = (int)((*(pkeys+1)) >> 24);
+ − 58
(*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
+ − 59
}
+ − 60
return c;
+ − 61
}
+ − 62
+ − 63
+ − 64
/***********************************************************************
+ − 65
* Initialize the encryption keys and the random header according to
+ − 66
* the given password.
+ − 67
*/
+ − 68
static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)
+ − 69
{
+ − 70
*(pkeys+0) = 305419896L;
+ − 71
*(pkeys+1) = 591751049L;
+ − 72
*(pkeys+2) = 878082192L;
+ − 73
while (*passwd != '\0') {
+ − 74
update_keys(pkeys,pcrc_32_tab,(int)*passwd);
+ − 75
passwd++;
+ − 76
}
+ − 77
}
+ − 78
+ − 79
#define zdecode(pkeys,pcrc_32_tab,c) \
+ − 80
(update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
+ − 81
+ − 82
#define zencode(pkeys,pcrc_32_tab,c,t) \
+ − 83
(t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
+ − 84
+ − 85
#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
+ − 86
+ − 87
#define RAND_HEAD_LEN 12
+ − 88
/* "last resort" source for second part of crypt seed pattern */
+ − 89
# ifndef ZCR_SEED2
+ − 90
# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
+ − 91
# endif
+ − 92
+ − 93
static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)
+ − 94
const char *passwd; /* password string */
+ − 95
unsigned char *buf; /* where to write header */
+ − 96
int bufSize;
+ − 97
unsigned long* pkeys;
+ − 98
const unsigned long* pcrc_32_tab;
+ − 99
unsigned long crcForCrypting;
+ − 100
{
+ − 101
int n; /* index in random header */
+ − 102
int t; /* temporary */
+ − 103
int c; /* random byte */
+ − 104
unsigned char header[RAND_HEAD_LEN-2]; /* random header */
+ − 105
static unsigned calls = 0; /* ensure different random header each time */
+ − 106
+ − 107
if (bufSize<RAND_HEAD_LEN)
+ − 108
return 0;
+ − 109
+ − 110
/* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
+ − 111
* output of rand() to get less predictability, since rand() is
+ − 112
* often poorly implemented.
+ − 113
*/
+ − 114
if (++calls == 1)
+ − 115
{
+ − 116
srand((unsigned)(time(NULL) ^ ZCR_SEED2));
+ − 117
}
+ − 118
init_keys(passwd, pkeys, pcrc_32_tab);
+ − 119
for (n = 0; n < RAND_HEAD_LEN-2; n++)
+ − 120
{
+ − 121
c = (rand() >> 7) & 0xff;
+ − 122
header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
+ − 123
}
+ − 124
/* Encrypt random header (last two bytes is high word of crc) */
+ − 125
init_keys(passwd, pkeys, pcrc_32_tab);
+ − 126
for (n = 0; n < RAND_HEAD_LEN-2; n++)
+ − 127
{
+ − 128
buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
+ − 129
}
+ − 130
buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
+ − 131
buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
+ − 132
return n;
+ − 133
}
+ − 134
+ − 135
#endif