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 */ 149int 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 */ 163int 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 */ 183void 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 212local 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 */ 231void 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 */ 271int 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 */ 326int 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 */ 422unsigned 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 */ 453int 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 b = NEXTBYTE; 469 h[n] = (uch)b; 470 Trace((stdout, " (%02x)", h[n])); 471 } 472 undefer_input(__G); 473 GLOBAL(pInfo->encrypted) = TRUE; 474 475 if (GLOBAL(newzip)) { /* this is first encrypted member in this zipfile */ 476 GLOBAL(newzip) = FALSE; 477 if (passwrd != (char *)NULL) { /* user gave password on command line */ 478 if (!GLOBAL(key)) { 479 if ((GLOBAL(key) = (char *)malloc(strlen(passwrd)+1)) == 480 (char *)NULL) 481 return PK_MEM2; 482 strcpy(GLOBAL(key), passwrd); 483 GLOBAL(nopwd) = TRUE; /* inhibit password prompting! */ 484 } 485 } else if (GLOBAL(key)) { /* get rid of previous zipfile's key */ 486 free(GLOBAL(key)); 487 GLOBAL(key) = (char *)NULL; 488 } 489 } 490 491 /* if have key already, test it; else allocate memory for it */ 492 if (GLOBAL(key)) { 493 if (!testp(__G__ h)) 494 return PK_COOL; /* existing password OK (else prompt for new) */ 495 else if (GLOBAL(nopwd)) 496 return PK_WARN; /* user indicated no more prompting */ 497 } else if ((GLOBAL(key) = (char *)malloc(IZ_PWLEN+1)) == (char *)NULL) 498 return PK_MEM2; 499 500 /* try a few keys */ 501 n = 0; 502 do { 503 r = (*G.decr_passwd)((zvoid *)&G, &n, GLOBAL(key), IZ_PWLEN+1, 504 GLOBAL(zipfn), GLOBAL(filename)); 505 if (r == IZ_PW_ERROR) { /* internal error in fetch of PW */ 506 free (GLOBAL(key)); 507 GLOBAL(key) = NULL; 508 return PK_MEM2; 509 } 510 if (r != IZ_PW_ENTERED) { /* user replied "skip" or "skip all" */ 511 *GLOBAL(key) = '\0'; /* We try the NIL password, ... */ 512 n = 0; /* and cancel fetch for this item. */ 513 } 514 if (!testp(__G__ h)) 515 return PK_COOL; 516 if (r == IZ_PW_CANCELALL) /* User replied "Skip all" */ 517 GLOBAL(nopwd) = TRUE; /* inhibit any further PW prompt! */ 518 } while (n > 0); 519 520 return PK_WARN; 521 522} /* end function decrypt() */ 523 524 525 526/*********************************************************************** 527 * Test the password. Return -1 if bad, 0 if OK. 528 */ 529local int testp(__G__ h) 530 __GDEF 531 ZCONST uch *h; 532{ 533 int r; 534 char *key_translated; 535 536 /* On systems with "obscure" native character coding (e.g., EBCDIC), 537 * the first test translates the password to the "main standard" 538 * character coding. */ 539 540#ifdef STR_TO_CP1 541 /* allocate buffer for translated password */ 542 if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL) 543 return -1; 544 /* first try, test password translated "standard" charset */ 545 r = testkey(__G__ h, STR_TO_CP1(key_translated, GLOBAL(key))); 546#else /* !STR_TO_CP1 */ 547 /* first try, test password as supplied on the extractor's host */ 548 r = testkey(__G__ h, GLOBAL(key)); 549#endif /* ?STR_TO_CP1 */ 550 551#ifdef STR_TO_CP2 552 if (r != 0) { 553#ifndef STR_TO_CP1 554 /* now prepare for second (and maybe third) test with translated pwd */ 555 if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL) 556 return -1; 557#endif 558 /* second try, password translated to alternate ("standard") charset */ 559 r = testkey(__G__ h, STR_TO_CP2(key_translated, GLOBAL(key))); 560#ifdef STR_TO_CP3 561 if (r != 0) 562 /* third try, password translated to another "standard" charset */ 563 r = testkey(__G__ h, STR_TO_CP3(key_translated, GLOBAL(key))); 564#endif 565#ifndef STR_TO_CP1 566 free(key_translated); 567#endif 568 } 569#endif /* STR_TO_CP2 */ 570 571#ifdef STR_TO_CP1 572 free(key_translated); 573 if (r != 0) { 574 /* last resort, test password as supplied on the extractor's host */ 575 r = testkey(__G__ h, GLOBAL(key)); 576 } 577#endif /* STR_TO_CP1 */ 578 579 return r; 580 581} /* end function testp() */ 582 583 584local int testkey(__G__ h, key) 585 __GDEF 586 ZCONST uch *h; /* decrypted header */ 587 ZCONST char *key; /* decryption password to test */ 588{ 589 ush b; 590#ifdef ZIP10 591 ush c; 592#endif 593 int n; 594 uch *p; 595 uch hh[RAND_HEAD_LEN]; /* decrypted header */ 596 597 /* set keys and save the encrypted header */ 598 init_keys(__G__ key); 599 memcpy(hh, h, RAND_HEAD_LEN); 600 601 /* check password */ 602 for (n = 0; n < RAND_HEAD_LEN; n++) { 603 zdecode(hh[n]); 604 Trace((stdout, " %02x", hh[n])); 605 } 606 607 Trace((stdout, 608 "\n lrec.crc= %08lx crec.crc= %08lx pInfo->ExtLocHdr= %s\n", 609 GLOBAL(lrec.crc32), GLOBAL(pInfo->crc), 610 GLOBAL(pInfo->ExtLocHdr) ? "true":"false")); 611 Trace((stdout, " incnt = %d unzip offset into zipfile = %ld\n", 612 GLOBAL(incnt), 613 GLOBAL(cur_zipfile_bufstart)+(GLOBAL(inptr)-GLOBAL(inbuf)))); 614 615 /* same test as in zipbare(): */ 616 617#ifdef ZIP10 /* check two bytes */ 618 c = hh[RAND_HEAD_LEN-2], b = hh[RAND_HEAD_LEN-1]; 619 Trace((stdout, 620 " (c | (b<<8)) = %04x (crc >> 16) = %04x lrec.time = %04x\n", 621 (ush)(c | (b<<8)), (ush)(GLOBAL(lrec.crc32) >> 16), 622 ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff)))); 623 if ((ush)(c | (b<<8)) != (GLOBAL(pInfo->ExtLocHdr) ? 624 ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff) : 625 (ush)(GLOBAL(lrec.crc32) >> 16))) 626 return -1; /* bad */ 627#else 628 b = hh[RAND_HEAD_LEN-1]; 629 Trace((stdout, " b = %02x (crc >> 24) = %02x (lrec.time >> 8) = %02x\n", 630 b, (ush)(GLOBAL(lrec.crc32) >> 24), 631 ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff)); 632 if (b != (GLOBAL(pInfo->ExtLocHdr) ? 633 ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff : 634 (ush)(GLOBAL(lrec.crc32) >> 24))) 635 return -1; /* bad */ 636#endif 637 /* password OK: decrypt current buffer contents before leaving */ 638 for (n = (long)GLOBAL(incnt) > GLOBAL(csize) ? 639 (int)GLOBAL(csize) : GLOBAL(incnt), 640 p = GLOBAL(inptr); n--; p++) 641 zdecode(*p); 642 return 0; /* OK */ 643 644} /* end function testkey() */ 645 646#endif /* UNZIP && !FUNZIP */ 647 648#else /* !CRYPT */ 649 650/* something "externally visible" to shut up compiler/linker warnings */ 651int zcr_dummy; 652 653#endif /* ?CRYPT */ 654