xref: /minix3/common/dist/zlib/contrib/minizip/crypt.h (revision 44bedb31d842b4b0444105519bcf929a69fe2dc1)
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