1 /*
2 Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
3
4 See the accompanying file LICENSE, version 2005-Feb-10 or later
5 (the contents of which are also included in (un)zip.h) for terms of use.
6 If, for some reason, all these files are missing, the Info-ZIP license
7 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
8 */
9 /*
10 crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
11
12 The main encryption/decryption source code for Info-Zip software was
13 originally written in Europe. To the best of our knowledge, it can
14 be freely distributed in both source and object forms from any country,
15 including the USA under License Exception TSU of the U.S. Export
16 Administration Regulations (section 740.13(e)) of 6 June 2002.
17
18 NOTE on copyright history:
19 Previous versions of this source package (up to version 2.8) were
20 not copyrighted and put in the public domain. If you cannot comply
21 with the Info-Zip LICENSE, you may want to look for one of those
22 public domain versions.
23 */
24
25 /*
26 This encryption code is a direct transcription of the algorithm from
27 Roger Schlafly, described by Phil Katz in the file appnote.txt. This
28 file (appnote.txt) is distributed with the PKZIP program (even in the
29 version without encryption capabilities).
30 */
31
32 #define ZCRYPT_INTERNAL
33 #include "zip.h"
34 #include "crypt.h"
35 #include "ttyio.h"
36
37 #if CRYPT
38
39 #ifndef FALSE
40 # define FALSE 0
41 #endif
42
43 #ifdef ZIP
44 /* For the encoding task used in Zip (and ZipCloak), we want to initialize
45 the crypt algorithm with some reasonably unpredictable bytes, see
46 the crypthead() function. The standard rand() library function is
47 used to supply these `random' bytes, which in turn is initialized by
48 a srand() call. The srand() function takes an "unsigned" (at least 16bit)
49 seed value as argument to determine the starting point of the rand()
50 pseudo-random number generator.
51 This seed number is constructed as "Seed = Seed1 .XOR. Seed2" with
52 Seed1 supplied by the current time (= "(unsigned)time()") and Seed2
53 as some (hopefully) nondeterministic bitmask. On many (most) systems,
54 we use some "process specific" number, as the PID or something similar,
55 but when nothing unpredictable is available, a fixed number may be
56 sufficient.
57 NOTE:
58 1.) This implementation requires the availability of the following
59 standard UNIX C runtime library functions: time(), rand(), srand().
60 On systems where some of them are missing, the environment that
61 incorporates the crypt routines must supply suitable replacement
62 functions.
63 2.) It is a very bad idea to use a second call to time() to set the
64 "Seed2" number! In this case, both "Seed1" and "Seed2" would be
65 (almost) identical, resulting in a (mostly) "zero" constant seed
66 number passed to srand().
67
68 The implementation environment defined in the "zip.h" header should
69 supply a reasonable definition for ZCR_SEED2 (an unsigned number; for
70 most implementations of rand() and srand(), only the lower 16 bits are
71 significant!). An example that works on many systems would be
72 "#define ZCR_SEED2 (unsigned)getpid()".
73 The default definition for ZCR_SEED2 supplied below should be regarded
74 as a fallback to allow successful compilation in "beta state"
75 environments.
76 */
77 # include <time.h> /* time() function supplies first part of crypt seed */
78 /* "last resort" source for second part of crypt seed pattern */
79 # ifndef ZCR_SEED2
80 # define ZCR_SEED2 (unsigned)3141592654L /* use PI as default pattern */
81 # endif
82 # ifdef GLOBAL /* used in Amiga system headers, maybe others too */
83 # undef GLOBAL
84 # endif
85 # define GLOBAL(g) g
86 #else /* !ZIP */
87 # define GLOBAL(g) G.g
88 #endif /* ?ZIP */
89
90
91 #ifdef UNZIP
92 /* char *key = (char *)NULL; moved to globals.h */
93 # ifndef FUNZIP
94 local int testp OF((__GPRO__ ZCONST uch *h));
95 local int testkey OF((__GPRO__ ZCONST uch *h, ZCONST char *key));
96 # endif
97 #endif /* UNZIP */
98
99 #ifndef UNZIP /* moved to globals.h for UnZip */
100 # ifndef Z_UINT4_DEFINED
101 # if !defined(NO_LIMITS_H)
102 # if (defined(UINT_MAX) && (UINT_MAX == 0xffffffffUL))
103 typedef unsigned int z_uint4;
104 # define Z_UINT4_DEFINED
105 # else
106 # if (defined(ULONG_MAX) && (ULONG_MAX == 0xffffffffUL))
107 typedef unsigned long z_uint4;
108 # define Z_UINT4_DEFINED
109 # else
110 # if (defined(USHRT_MAX) && (USHRT_MAX == 0xffffffffUL))
111 typedef unsigned short z_uint4;
112 # define Z_UINT4_DEFINED
113 # endif
114 # endif
115 # endif
116 # endif /* !NO_LIMITS_H */
117 # endif /* !Z_UINT4_DEFINED */
118 # ifndef Z_UINT4_DEFINED
119 typedef ulg z_uint4;
120 # define Z_UINT4_DEFINED
121 # endif
122 local z_uint4 keys[3]; /* keys defining the pseudo-random sequence */
123 #endif /* !UNZIP */
124
125 #ifndef Trace
126 # ifdef CRYPT_DEBUG
127 # define Trace(x) fprintf x
128 # else
129 # define Trace(x)
130 # endif
131 #endif
132
133 #include "crc32.h"
134
135 #ifdef IZ_CRC_BE_OPTIMIZ
136 local z_uint4 near crycrctab[256];
137 local z_uint4 near *cry_crctb_p = NULL;
138 local z_uint4 near *crytab_init OF((__GPRO));
139 # define CRY_CRC_TAB cry_crctb_p
140 # undef CRC32
141 # define CRC32(c, b, crctab) (crctab[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
142 #else
143 # define CRY_CRC_TAB CRC_32_TAB
144 #endif /* ?IZ_CRC_BE_OPTIMIZ */
145
146 /***********************************************************************
147 * Return the next byte in the pseudo-random sequence
148 */
decrypt_byte(__G)149 int decrypt_byte(__G)
150 __GDEF
151 {
152 unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
153 * unpredictable manner on 16-bit systems; not a problem
154 * with any known compiler so far, though */
155
156 temp = ((unsigned)GLOBAL(keys[2]) & 0xffff) | 2;
157 return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
158 }
159
160 /***********************************************************************
161 * Update the encryption keys with the next byte of plain text
162 */
163 int update_keys(__G__ c)
164 __GDEF
165 int c; /* byte of plain text */
166 {
167 GLOBAL(keys[0]) = CRC32(GLOBAL(keys[0]), c, CRY_CRC_TAB);
168 GLOBAL(keys[1]) = (GLOBAL(keys[1])
169 + (GLOBAL(keys[0]) & 0xff))
170 * 134775813L + 1;
171 {
172 register int keyshift = (int)(GLOBAL(keys[1]) >> 24);
173 GLOBAL(keys[2]) = CRC32(GLOBAL(keys[2]), keyshift, CRY_CRC_TAB);
174 }
175 return c;
176 }
177
178
179 /***********************************************************************
180 * Initialize the encryption keys and the random header according to
181 * the given password.
182 */
183 void init_keys(__G__ passwd)
184 __GDEF
185 ZCONST char *passwd; /* password string with which to modify keys */
186 {
187 #ifdef IZ_CRC_BE_OPTIMIZ
188 if (cry_crctb_p == NULL) {
189 cry_crctb_p = crytab_init(__G);
190 }
191 #endif
192 GLOBAL(keys[0]) = 305419896L;
193 GLOBAL(keys[1]) = 591751049L;
194 GLOBAL(keys[2]) = 878082192L;
195 while (*passwd != '\0') {
196 update_keys(__G__ (int)*passwd);
197 passwd++;
198 }
199 }
200
201
202 /***********************************************************************
203 * Initialize the local copy of the table of precomputed crc32 values.
204 * Whereas the public crc32-table is optimized for crc32 calculations
205 * on arrays of bytes, the crypt code needs the crc32 values in an
206 * byte-order-independent form as 32-bit unsigned numbers. On systems
207 * with Big-Endian byte order using the optimized crc32 code, this
208 * requires inverting the byte-order of the values in the
209 * crypt-crc32-table.
210 */
211 #ifdef IZ_CRC_BE_OPTIMIZ
crytab_init(__G)212 local z_uint4 near *crytab_init(__G)
213 __GDEF
214 {
215 int i;
216
217 for (i = 0; i < 256; i++) {
218 crycrctab[i] = REV_BE(CRC_32_TAB[i]);
219 }
220 return crycrctab;
221 }
222 #endif
223
224
225 #ifdef ZIP
226
227 /***********************************************************************
228 * Write encryption header to file zfile using the password passwd
229 * and the cyclic redundancy check crc.
230 */
crypthead(passwd,crc,zfile)231 void crypthead(passwd, crc, zfile)
232 ZCONST char *passwd; /* password string */
233 ulg crc; /* crc of file being encrypted */
234 FILE *zfile; /* where to write header */
235 {
236 int n; /* index in random header */
237 int t; /* temporary */
238 int c; /* random byte */
239 uch header[RAND_HEAD_LEN]; /* random header */
240 static unsigned calls = 0; /* ensure different random header each time */
241
242 /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
243 * output of rand() to get less predictability, since rand() is
244 * often poorly implemented.
245 */
246 if (++calls == 1) {
247 srand((unsigned)time(NULL) ^ ZCR_SEED2);
248 }
249 init_keys(passwd);
250 for (n = 0; n < RAND_HEAD_LEN-2; n++) {
251 c = (rand() >> 7) & 0xff;
252 header[n] = (uch)zencode(c, t);
253 }
254 /* Encrypt random header (last two bytes is high word of crc) */
255 init_keys(passwd);
256 for (n = 0; n < RAND_HEAD_LEN-2; n++) {
257 header[n] = (uch)zencode(header[n], t);
258 }
259 header[RAND_HEAD_LEN-2] = (uch)zencode((int)(crc >> 16) & 0xff, t);
260 header[RAND_HEAD_LEN-1] = (uch)zencode((int)(crc >> 24) & 0xff, t);
261 fwrite(header, 1, RAND_HEAD_LEN, f);
262 }
263
264
265 #ifdef UTIL
266
267 /***********************************************************************
268 * Encrypt the zip entry described by z from file source to file dest
269 * using the password passwd. Return an error code in the ZE_ class.
270 */
zipcloak(z,source,dest,passwd)271 int zipcloak(z, source, dest, passwd)
272 struct zlist far *z; /* zip entry to encrypt */
273 FILE *source, *dest; /* source and destination files */
274 ZCONST char *passwd; /* password string */
275 {
276 int c; /* input byte */
277 int res; /* result code */
278 ulg n; /* holds offset and counts size */
279 ush flag; /* previous flags */
280 int t; /* temporary */
281 int ztemp; /* temporary storage for zencode value */
282
283 /* Set encrypted bit, clear extended local header bit and write local
284 header to output file */
285 if ((n = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
286 z->off = n;
287 flag = z->flg;
288 z->flg |= 1, z->flg &= ~8;
289 z->lflg |= 1, z->lflg &= ~8;
290 z->siz += RAND_HEAD_LEN;
291 if ((res = putlocal(z, dest)) != ZE_OK) return res;
292
293 /* Initialize keys with password and write random header */
294 crypthead(passwd, z->crc, dest);
295
296 /* Skip local header in input file */
297 if (fseek(source, (long)((4 + LOCHEAD) + (ulg)z->nam + (ulg)z->ext),
298 SEEK_CUR)) {
299 return ferror(source) ? ZE_READ : ZE_EOF;
300 }
301
302 /* Encrypt data */
303 for (n = z->siz - RAND_HEAD_LEN; n; n--) {
304 if ((c = getc(source)) == EOF) {
305 return ferror(source) ? ZE_READ : ZE_EOF;
306 }
307 ztemp = zencode(c, t);
308 putc(ztemp, dest);
309 }
310 /* Skip extended local header in input file if there is one */
311 if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
312 return ferror(source) ? ZE_READ : ZE_EOF;
313 }
314 if (fflush(dest) == EOF) return ZE_TEMP;
315
316 /* Update number of bytes written to output file */
317 tempzn += (4 + LOCHEAD) + z->nam + z->ext + z->siz;
318
319 return ZE_OK;
320 }
321
322 /***********************************************************************
323 * Decrypt the zip entry described by z from file source to file dest
324 * using the password passwd. Return an error code in the ZE_ class.
325 */
zipbare(z,source,dest,passwd)326 int zipbare(z, source, dest, passwd)
327 struct zlist far *z; /* zip entry to encrypt */
328 FILE *source, *dest; /* source and destination files */
329 ZCONST char *passwd; /* password string */
330 {
331 #ifdef ZIP10
332 int c0 /* byte preceding the last input byte */
333 #endif
334 int c1; /* last input byte */
335 ulg offset; /* used for file offsets */
336 ulg size; /* size of input data */
337 int r; /* size of encryption header */
338 int res; /* return code */
339 ush flag; /* previous flags */
340
341 /* Save position and skip local header in input file */
342 if ((offset = (ulg)ftell(source)) == (ulg)-1L ||
343 fseek(source, (long)((4 + LOCHEAD) + (ulg)z->nam + (ulg)z->ext),
344 SEEK_CUR)) {
345 return ferror(source) ? ZE_READ : ZE_EOF;
346 }
347 /* Initialize keys with password */
348 init_keys(passwd);
349
350 /* Decrypt encryption header, save last two bytes */
351 c1 = 0;
352 for (r = RAND_HEAD_LEN; r; r--) {
353 #ifdef ZIP10
354 c0 = c1;
355 #endif
356 if ((c1 = getc(source)) == EOF) {
357 return ferror(source) ? ZE_READ : ZE_EOF;
358 }
359 Trace((stdout, " (%02x)", c1));
360 zdecode(c1);
361 Trace((stdout, " %02x", c1));
362 }
363 Trace((stdout, "\n"));
364
365 /* If last two bytes of header don't match crc (or file time in the
366 * case of an extended local header), back up and just copy. For
367 * pkzip 2.0, the check has been reduced to one byte only.
368 */
369 #ifdef ZIP10
370 if ((ush)(c0 | (c1<<8)) !=
371 (z->flg & 8 ? (ush) z->tim & 0xffff : (ush)(z->crc >> 16))) {
372 #else
373 if ((ush)c1 != (z->flg & 8 ? (ush) z->tim >> 8 : (ush)(z->crc >> 24))) {
374 #endif
375 if (fseek(source, offset, SEEK_SET)) {
376 return ferror(source) ? ZE_READ : ZE_EOF;
377 }
378 if ((res = zipcopy(z, source, dest)) != ZE_OK) return res;
379 return ZE_MISS;
380 }
381
382 /* Clear encrypted bit and local header bit, and write local header to
383 output file */
384 if ((offset = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
385 z->off = offset;
386 flag = z->flg;
387 z->flg &= ~9;
388 z->lflg &= ~9;
389 z->siz -= RAND_HEAD_LEN;
390 if ((res = putlocal(z, dest)) != ZE_OK) return res;
391
392 /* Decrypt data */
393 for (size = z->siz; size; size--) {
394 if ((c1 = getc(source)) == EOF) {
395 return ferror(source) ? ZE_READ : ZE_EOF;
396 }
397 zdecode(c1);
398 putc(c1, dest);
399 }
400 /* Skip extended local header in input file if there is one */
401 if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
402 return ferror(source) ? ZE_READ : ZE_EOF;
403 }
404 if (fflush(dest) == EOF) return ZE_TEMP;
405
406 /* Update number of bytes written to output file */
407 tempzn += (4 + LOCHEAD) + z->nam + z->ext + z->siz;
408
409 return ZE_OK;
410 }
411
412
413 #else /* !UTIL */
414
415 /***********************************************************************
416 * If requested, encrypt the data in buf, and in any case call fwrite()
417 * with the arguments to zfwrite(). Return what fwrite() returns.
418 *
419 * A bug has been found when encrypting large files. See trees.c
420 * for details and the fix.
421 */
zfwrite(buf,item_size,nb,f)422 unsigned zfwrite(buf, item_size, nb, f)
423 zvoid *buf; /* data buffer */
424 extent item_size; /* size of each item in bytes */
425 extent nb; /* number of items */
426 FILE *f; /* file to write to */
427 {
428 int t; /* temporary */
429
430 if (key != (char *)NULL) { /* key is the global password pointer */
431 ulg size; /* buffer size */
432 char *p = (char*)buf; /* steps through buffer */
433
434 /* Encrypt data in buffer */
435 for (size = item_size*(ulg)nb; size != 0; p++, size--) {
436 *p = (char)zencode(*p, t);
437 }
438 }
439 /* Write the buffer out */
440 return fwrite(buf, item_size, nb, f);
441 }
442
443 #endif /* ?UTIL */
444 #endif /* ZIP */
445
446
447 #if (defined(UNZIP) && !defined(FUNZIP))
448
449 /***********************************************************************
450 * Get the password and set up keys for current zipfile member.
451 * Return PK_ class error.
452 */
453 int decrypt(__G__ passwrd)
454 __GDEF
455 ZCONST char *passwrd;
456 {
457 ush b;
458 int n, r;
459 uch h[RAND_HEAD_LEN];
460
461 Trace((stdout, "\n[incnt = %d]: ", GLOBAL(incnt)));
462
463 /* get header once (turn off "encrypted" flag temporarily so we don't
464 * try to decrypt the same data twice) */
465 GLOBAL(pInfo->encrypted) = FALSE;
466 defer_leftover_input(__G);
467 for (n = 0; n < RAND_HEAD_LEN; n++) {
468 /* 2012-11-23 SMS. (OUSPG report.)
469 * Quit early if compressed size < HEAD_LEN. The resulting
470 * error message ("unable to get password") could be improved,
471 * but it's better than trying to read nonexistent data, and
472 * then continuing with a negative G.csize. (See
473 * fileio.c:readbyte()).
474 */
475 if ((b = NEXTBYTE) == (ush)EOF)
476 {
477 return PK_ERR;
478 }
479 h[n] = (uch)b;
480 Trace((stdout, " (%02x)", h[n]));
481 }
482 undefer_input(__G);
483 GLOBAL(pInfo->encrypted) = TRUE;
484
485 if (GLOBAL(newzip)) { /* this is first encrypted member in this zipfile */
486 GLOBAL(newzip) = FALSE;
487 if (passwrd != (char *)NULL) { /* user gave password on command line */
488 if (!GLOBAL(key)) {
489 if ((GLOBAL(key) = (char *)malloc(strlen(passwrd)+1)) ==
490 (char *)NULL)
491 return PK_MEM2;
492 strcpy(GLOBAL(key), passwrd);
493 GLOBAL(nopwd) = TRUE; /* inhibit password prompting! */
494 }
495 } else if (GLOBAL(key)) { /* get rid of previous zipfile's key */
496 free(GLOBAL(key));
497 GLOBAL(key) = (char *)NULL;
498 }
499 }
500
501 /* if have key already, test it; else allocate memory for it */
502 if (GLOBAL(key)) {
503 if (!testp(__G__ h))
504 return PK_COOL; /* existing password OK (else prompt for new) */
505 else if (GLOBAL(nopwd))
506 return PK_WARN; /* user indicated no more prompting */
507 } else if ((GLOBAL(key) = (char *)malloc(IZ_PWLEN+1)) == (char *)NULL)
508 return PK_MEM2;
509
510 /* try a few keys */
511 n = 0;
512 do {
513 r = (*G.decr_passwd)((zvoid *)&G, &n, GLOBAL(key), IZ_PWLEN+1,
514 GLOBAL(zipfn), GLOBAL(filename));
515 if (r == IZ_PW_ERROR) { /* internal error in fetch of PW */
516 free (GLOBAL(key));
517 GLOBAL(key) = NULL;
518 return PK_MEM2;
519 }
520 if (r != IZ_PW_ENTERED) { /* user replied "skip" or "skip all" */
521 *GLOBAL(key) = '\0'; /* We try the NIL password, ... */
522 n = 0; /* and cancel fetch for this item. */
523 }
524 if (!testp(__G__ h))
525 return PK_COOL;
526 if (r == IZ_PW_CANCELALL) /* User replied "Skip all" */
527 GLOBAL(nopwd) = TRUE; /* inhibit any further PW prompt! */
528 } while (n > 0);
529
530 return PK_WARN;
531
532 } /* end function decrypt() */
533
534
535
536 /***********************************************************************
537 * Test the password. Return -1 if bad, 0 if OK.
538 */
539 local int testp(__G__ h)
540 __GDEF
541 ZCONST uch *h;
542 {
543 int r;
544 char *key_translated;
545
546 /* On systems with "obscure" native character coding (e.g., EBCDIC),
547 * the first test translates the password to the "main standard"
548 * character coding. */
549
550 #ifdef STR_TO_CP1
551 /* allocate buffer for translated password */
552 if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL)
553 return -1;
554 /* first try, test password translated "standard" charset */
555 r = testkey(__G__ h, STR_TO_CP1(key_translated, GLOBAL(key)));
556 #else /* !STR_TO_CP1 */
557 /* first try, test password as supplied on the extractor's host */
558 r = testkey(__G__ h, GLOBAL(key));
559 #endif /* ?STR_TO_CP1 */
560
561 #ifdef STR_TO_CP2
562 if (r != 0) {
563 #ifndef STR_TO_CP1
564 /* now prepare for second (and maybe third) test with translated pwd */
565 if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL)
566 return -1;
567 #endif
568 /* second try, password translated to alternate ("standard") charset */
569 r = testkey(__G__ h, STR_TO_CP2(key_translated, GLOBAL(key)));
570 #ifdef STR_TO_CP3
571 if (r != 0)
572 /* third try, password translated to another "standard" charset */
573 r = testkey(__G__ h, STR_TO_CP3(key_translated, GLOBAL(key)));
574 #endif
575 #ifndef STR_TO_CP1
576 free(key_translated);
577 #endif
578 }
579 #endif /* STR_TO_CP2 */
580
581 #ifdef STR_TO_CP1
582 free(key_translated);
583 if (r != 0) {
584 /* last resort, test password as supplied on the extractor's host */
585 r = testkey(__G__ h, GLOBAL(key));
586 }
587 #endif /* STR_TO_CP1 */
588
589 return r;
590
591 } /* end function testp() */
592
593
594 local int testkey(__G__ h, key)
595 __GDEF
596 ZCONST uch *h; /* decrypted header */
597 ZCONST char *key; /* decryption password to test */
598 {
599 ush b;
600 #ifdef ZIP10
601 ush c;
602 #endif
603 int n;
604 uch *p;
605 uch hh[RAND_HEAD_LEN]; /* decrypted header */
606
607 /* set keys and save the encrypted header */
608 init_keys(__G__ key);
609 memcpy(hh, h, RAND_HEAD_LEN);
610
611 /* check password */
612 for (n = 0; n < RAND_HEAD_LEN; n++) {
613 zdecode(hh[n]);
614 Trace((stdout, " %02x", hh[n]));
615 }
616
617 Trace((stdout,
618 "\n lrec.crc= %08lx crec.crc= %08lx pInfo->ExtLocHdr= %s\n",
619 GLOBAL(lrec.crc32), GLOBAL(pInfo->crc),
620 GLOBAL(pInfo->ExtLocHdr) ? "true":"false"));
621 Trace((stdout, " incnt = %d unzip offset into zipfile = %ld\n",
622 GLOBAL(incnt),
623 GLOBAL(cur_zipfile_bufstart)+(GLOBAL(inptr)-GLOBAL(inbuf))));
624
625 /* same test as in zipbare(): */
626
627 #ifdef ZIP10 /* check two bytes */
628 c = hh[RAND_HEAD_LEN-2], b = hh[RAND_HEAD_LEN-1];
629 Trace((stdout,
630 " (c | (b<<8)) = %04x (crc >> 16) = %04x lrec.time = %04x\n",
631 (ush)(c | (b<<8)), (ush)(GLOBAL(lrec.crc32) >> 16),
632 ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff))));
633 if ((ush)(c | (b<<8)) != (GLOBAL(pInfo->ExtLocHdr) ?
634 ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff) :
635 (ush)(GLOBAL(lrec.crc32) >> 16)))
636 return -1; /* bad */
637 #else
638 b = hh[RAND_HEAD_LEN-1];
639 Trace((stdout, " b = %02x (crc >> 24) = %02x (lrec.time >> 8) = %02x\n",
640 b, (ush)(GLOBAL(lrec.crc32) >> 24),
641 ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff));
642 if (b != (GLOBAL(pInfo->ExtLocHdr) ?
643 ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff :
644 (ush)(GLOBAL(lrec.crc32) >> 24)))
645 return -1; /* bad */
646 #endif
647 /* password OK: decrypt current buffer contents before leaving */
648 for (n = (long)GLOBAL(incnt) > GLOBAL(csize) ?
649 (int)GLOBAL(csize) : GLOBAL(incnt),
650 p = GLOBAL(inptr); n--; p++)
651 zdecode(*p);
652 return 0; /* OK */
653
654 } /* end function testkey() */
655
656 #endif /* UNZIP && !FUNZIP */
657
658 #else /* !CRYPT */
659
660 /* something "externally visible" to shut up compiler/linker warnings */
661 int zcr_dummy;
662
663 #endif /* ?CRYPT */
664