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