1/* 2 Copyright (c) 1990-2006 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 local ulg keys[3]; /* keys defining the pseudo-random sequence */ 101#endif /* !UNZIP */ 102 103#ifndef Trace 104# ifdef CRYPT_DEBUG 105# define Trace(x) fprintf x 106# else 107# define Trace(x) 108# endif 109#endif 110 111#ifndef CRC_32_TAB 112# define CRC_32_TAB crc_32_tab 113#endif 114 115#define CRC32(c, b) (CRC_32_TAB[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8)) 116 117/*********************************************************************** 118 * Return the next byte in the pseudo-random sequence 119 */ 120int decrypt_byte(__G) 121 __GDEF 122{ 123 unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an 124 * unpredictable manner on 16-bit systems; not a problem 125 * with any known compiler so far, though */ 126 127 temp = ((unsigned)GLOBAL(keys[2]) & 0xffff) | 2; 128 return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); 129} 130 131/*********************************************************************** 132 * Update the encryption keys with the next byte of plain text 133 */ 134int update_keys(__G__ c) 135 __GDEF 136 int c; /* byte of plain text */ 137{ 138 GLOBAL(keys[0]) = CRC32(GLOBAL(keys[0]), c); 139 GLOBAL(keys[1]) += GLOBAL(keys[0]) & 0xff; 140 GLOBAL(keys[1]) = GLOBAL(keys[1]) * 134775813L + 1; 141 { 142 register int keyshift = (int)(GLOBAL(keys[1]) >> 24); 143 GLOBAL(keys[2]) = CRC32(GLOBAL(keys[2]), keyshift); 144 } 145 return c; 146} 147 148 149/*********************************************************************** 150 * Initialize the encryption keys and the random header according to 151 * the given password. 152 */ 153void init_keys(__G__ passwd) 154 __GDEF 155 ZCONST char *passwd; /* password string with which to modify keys */ 156{ 157 GLOBAL(keys[0]) = 305419896L; 158 GLOBAL(keys[1]) = 591751049L; 159 GLOBAL(keys[2]) = 878082192L; 160 while (*passwd != '\0') { 161 update_keys(__G__ (int)*passwd); 162 passwd++; 163 } 164} 165 166 167#ifdef ZIP 168 169/*********************************************************************** 170 * Write encryption header to file zfile using the password passwd 171 * and the cyclic redundancy check crc. 172 */ 173void crypthead(passwd, crc, zfile) 174 ZCONST char *passwd; /* password string */ 175 ulg crc; /* crc of file being encrypted */ 176 FILE *zfile; /* where to write header */ 177{ 178 int n; /* index in random header */ 179 int t; /* temporary */ 180 int c; /* random byte */ 181 int ztemp; /* temporary for zencoded value */ 182 uch header[RAND_HEAD_LEN-2]; /* random header */ 183 static unsigned calls = 0; /* ensure different random header each time */ 184 185 /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the 186 * output of rand() to get less predictability, since rand() is 187 * often poorly implemented. 188 */ 189 if (++calls == 1) { 190 srand((unsigned)time(NULL) ^ ZCR_SEED2); 191 } 192 init_keys(passwd); 193 for (n = 0; n < RAND_HEAD_LEN-2; n++) { 194 c = (rand() >> 7) & 0xff; 195 header[n] = (uch)zencode(c, t); 196 } 197 /* Encrypt random header (last two bytes is high word of crc) */ 198 init_keys(passwd); 199 for (n = 0; n < RAND_HEAD_LEN-2; n++) { 200 ztemp = zencode(header[n], t); 201 putc(ztemp, zfile); 202 } 203 ztemp = zencode((int)(crc >> 16) & 0xff, t); 204 putc(ztemp, zfile); 205 ztemp = zencode((int)(crc >> 24) & 0xff, t); 206 putc(ztemp, zfile); 207} 208 209 210#ifdef UTIL 211 212/*********************************************************************** 213 * Encrypt the zip entry described by z from file source to file dest 214 * using the password passwd. Return an error code in the ZE_ class. 215 */ 216int zipcloak(z, source, dest, passwd) 217 struct zlist far *z; /* zip entry to encrypt */ 218 FILE *source, *dest; /* source and destination files */ 219 ZCONST char *passwd; /* password string */ 220{ 221 int c; /* input byte */ 222 int res; /* result code */ 223 ulg n; /* holds offset and counts size */ 224 ush flag; /* previous flags */ 225 int t; /* temporary */ 226 int ztemp; /* temporary storage for zencode value */ 227 228 /* Set encrypted bit, clear extended local header bit and write local 229 header to output file */ 230 if ((n = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP; 231 z->off = n; 232 flag = z->flg; 233 z->flg |= 1, z->flg &= ~8; 234 z->lflg |= 1, z->lflg &= ~8; 235 z->siz += RAND_HEAD_LEN; 236 if ((res = putlocal(z, dest)) != ZE_OK) return res; 237 238 /* Initialize keys with password and write random header */ 239 crypthead(passwd, z->crc, dest); 240 241 /* Skip local header in input file */ 242 if (fseek(source, (long)((4 + LOCHEAD) + (ulg)z->nam + (ulg)z->ext), 243 SEEK_CUR)) { 244 return ferror(source) ? ZE_READ : ZE_EOF; 245 } 246 247 /* Encrypt data */ 248 for (n = z->siz - RAND_HEAD_LEN; n; n--) { 249 if ((c = getc(source)) == EOF) { 250 return ferror(source) ? ZE_READ : ZE_EOF; 251 } 252 ztemp = zencode(c, t); 253 putc(ztemp, dest); 254 } 255 /* Skip extended local header in input file if there is one */ 256 if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) { 257 return ferror(source) ? ZE_READ : ZE_EOF; 258 } 259 if (fflush(dest) == EOF) return ZE_TEMP; 260 261 /* Update number of bytes written to output file */ 262 tempzn += (4 + LOCHEAD) + z->nam + z->ext + z->siz; 263 264 return ZE_OK; 265} 266 267/*********************************************************************** 268 * Decrypt 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 zipbare(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#ifdef ZIP10 277 int c0 /* byte preceding the last input byte */ 278#endif 279 int c1; /* last input byte */ 280 ulg offset; /* used for file offsets */ 281 ulg size; /* size of input data */ 282 int r; /* size of encryption header */ 283 int res; /* return code */ 284 ush flag; /* previous flags */ 285 286 /* Save position and skip local header in input file */ 287 if ((offset = (ulg)ftell(source)) == (ulg)-1L || 288 fseek(source, (long)((4 + LOCHEAD) + (ulg)z->nam + (ulg)z->ext), 289 SEEK_CUR)) { 290 return ferror(source) ? ZE_READ : ZE_EOF; 291 } 292 /* Initialize keys with password */ 293 init_keys(passwd); 294 295 /* Decrypt encryption header, save last two bytes */ 296 c1 = 0; 297 for (r = RAND_HEAD_LEN; r; r--) { 298#ifdef ZIP10 299 c0 = c1; 300#endif 301 if ((c1 = getc(source)) == EOF) { 302 return ferror(source) ? ZE_READ : ZE_EOF; 303 } 304 Trace((stdout, " (%02x)", c1)); 305 zdecode(c1); 306 Trace((stdout, " %02x", c1)); 307 } 308 Trace((stdout, "\n")); 309 310 /* If last two bytes of header don't match crc (or file time in the 311 * case of an extended local header), back up and just copy. For 312 * pkzip 2.0, the check has been reduced to one byte only. 313 */ 314#ifdef ZIP10 315 if ((ush)(c0 | (c1<<8)) != 316 (z->flg & 8 ? (ush) z->tim & 0xffff : (ush)(z->crc >> 16))) { 317#else 318 if ((ush)c1 != (z->flg & 8 ? (ush) z->tim >> 8 : (ush)(z->crc >> 24))) { 319#endif 320 if (fseek(source, offset, SEEK_SET)) { 321 return ferror(source) ? ZE_READ : ZE_EOF; 322 } 323 if ((res = zipcopy(z, source, dest)) != ZE_OK) return res; 324 return ZE_MISS; 325 } 326 327 /* Clear encrypted bit and local header bit, and write local header to 328 output file */ 329 if ((offset = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP; 330 z->off = offset; 331 flag = z->flg; 332 z->flg &= ~9; 333 z->lflg &= ~9; 334 z->siz -= RAND_HEAD_LEN; 335 if ((res = putlocal(z, dest)) != ZE_OK) return res; 336 337 /* Decrypt data */ 338 for (size = z->siz; size; size--) { 339 if ((c1 = getc(source)) == EOF) { 340 return ferror(source) ? ZE_READ : ZE_EOF; 341 } 342 zdecode(c1); 343 putc(c1, dest); 344 } 345 /* Skip extended local header in input file if there is one */ 346 if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) { 347 return ferror(source) ? ZE_READ : ZE_EOF; 348 } 349 if (fflush(dest) == EOF) return ZE_TEMP; 350 351 /* Update number of bytes written to output file */ 352 tempzn += (4 + LOCHEAD) + z->nam + z->ext + z->siz; 353 354 return ZE_OK; 355} 356 357 358#else /* !UTIL */ 359 360/*********************************************************************** 361 * If requested, encrypt the data in buf, and in any case call fwrite() 362 * with the arguments to zfwrite(). Return what fwrite() returns. 363 * 364 * A bug has been found when encrypting large files. See trees.c 365 * for details and the fix. 366 */ 367unsigned zfwrite(buf, item_size, nb, f) 368 zvoid *buf; /* data buffer */ 369 extent item_size; /* size of each item in bytes */ 370 extent nb; /* number of items */ 371 FILE *f; /* file to write to */ 372{ 373 int t; /* temporary */ 374 375 if (key != (char *)NULL) { /* key is the global password pointer */ 376 ulg size; /* buffer size */ 377 char *p = (char*)buf; /* steps through buffer */ 378 379 /* Encrypt data in buffer */ 380 for (size = item_size*(ulg)nb; size != 0; p++, size--) { 381 *p = (char)zencode(*p, t); 382 } 383 } 384 /* Write the buffer out */ 385 return fwrite(buf, item_size, nb, f); 386} 387 388#endif /* ?UTIL */ 389#endif /* ZIP */ 390 391 392#if (defined(UNZIP) && !defined(FUNZIP)) 393 394/*********************************************************************** 395 * Get the password and set up keys for current zipfile member. 396 * Return PK_ class error. 397 */ 398int decrypt(__G__ passwrd) 399 __GDEF 400 ZCONST char *passwrd; 401{ 402 ush b; 403 int n, r; 404 uch h[RAND_HEAD_LEN]; 405 406 Trace((stdout, "\n[incnt = %d]: ", GLOBAL(incnt))); 407 408 /* get header once (turn off "encrypted" flag temporarily so we don't 409 * try to decrypt the same data twice) */ 410 GLOBAL(pInfo->encrypted) = FALSE; 411 defer_leftover_input(__G); 412 for (n = 0; n < RAND_HEAD_LEN; n++) { 413 b = NEXTBYTE; 414 h[n] = (uch)b; 415 Trace((stdout, " (%02x)", h[n])); 416 } 417 undefer_input(__G); 418 GLOBAL(pInfo->encrypted) = TRUE; 419 420 if (GLOBAL(newzip)) { /* this is first encrypted member in this zipfile */ 421 GLOBAL(newzip) = FALSE; 422 if (passwrd != (char *)NULL) { /* user gave password on command line */ 423 if (!GLOBAL(key)) { 424 if ((GLOBAL(key) = (char *)malloc(strlen(passwrd)+1)) == 425 (char *)NULL) 426 return PK_MEM2; 427 strcpy(GLOBAL(key), passwrd); 428 GLOBAL(nopwd) = TRUE; /* inhibit password prompting! */ 429 } 430 } else if (GLOBAL(key)) { /* get rid of previous zipfile's key */ 431 free(GLOBAL(key)); 432 GLOBAL(key) = (char *)NULL; 433 } 434 } 435 436 /* if have key already, test it; else allocate memory for it */ 437 if (GLOBAL(key)) { 438 if (!testp(__G__ h)) 439 return PK_COOL; /* existing password OK (else prompt for new) */ 440 else if (GLOBAL(nopwd)) 441 return PK_WARN; /* user indicated no more prompting */ 442 } else if ((GLOBAL(key) = (char *)malloc(IZ_PWLEN+1)) == (char *)NULL) 443 return PK_MEM2; 444 445 /* try a few keys */ 446 n = 0; 447 do { 448 r = (*G.decr_passwd)((zvoid *)&G, &n, GLOBAL(key), IZ_PWLEN+1, 449 GLOBAL(zipfn), GLOBAL(filename)); 450 if (r == IZ_PW_ERROR) { /* internal error in fetch of PW */ 451 free (GLOBAL(key)); 452 GLOBAL(key) = NULL; 453 return PK_MEM2; 454 } 455 if (r != IZ_PW_ENTERED) { /* user replied "skip" or "skip all" */ 456 *GLOBAL(key) = '\0'; /* We try the NIL password, ... */ 457 n = 0; /* and cancel fetch for this item. */ 458 } 459 if (!testp(__G__ h)) 460 return PK_COOL; 461 if (r == IZ_PW_CANCELALL) /* User replied "Skip all" */ 462 GLOBAL(nopwd) = TRUE; /* inhibit any further PW prompt! */ 463 } while (n > 0); 464 465 return PK_WARN; 466 467} /* end function decrypt() */ 468 469 470 471/*********************************************************************** 472 * Test the password. Return -1 if bad, 0 if OK. 473 */ 474local int testp(__G__ h) 475 __GDEF 476 ZCONST uch *h; 477{ 478 int r; 479 char *key_translated; 480 481 /* On systems with "obscure" native character coding (e.g., EBCDIC), 482 * the first test translates the password to the "main standard" 483 * character coding. */ 484 485#ifdef STR_TO_CP1 486 /* allocate buffer for translated password */ 487 if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL) 488 return -1; 489 /* first try, test password translated "standard" charset */ 490 r = testkey(__G__ h, STR_TO_CP1(key_translated, GLOBAL(key))); 491#else /* !STR_TO_CP1 */ 492 /* first try, test password as supplied on the extractor's host */ 493 r = testkey(__G__ h, GLOBAL(key)); 494#endif /* ?STR_TO_CP1 */ 495 496#ifdef STR_TO_CP2 497 if (r != 0) { 498#ifndef STR_TO_CP1 499 /* now prepare for second (and maybe third) test with translated pwd */ 500 if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL) 501 return -1; 502#endif 503 /* second try, password translated to alternate ("standard") charset */ 504 r = testkey(__G__ h, STR_TO_CP2(key_translated, GLOBAL(key))); 505#ifdef STR_TO_CP3 506 if (r != 0) 507 /* third try, password translated to another "standard" charset */ 508 r = testkey(__G__ h, STR_TO_CP3(key_translated, GLOBAL(key))); 509#endif 510#ifndef STR_TO_CP1 511 free(key_translated); 512#endif 513 } 514#endif /* STR_TO_CP2 */ 515 516#ifdef STR_TO_CP1 517 free(key_translated); 518 if (r != 0) { 519 /* last resort, test password as supplied on the extractor's host */ 520 r = testkey(__G__ h, GLOBAL(key)); 521 } 522#endif /* STR_TO_CP1 */ 523 524 return r; 525 526} /* end function testp() */ 527 528 529local int testkey(__G__ h, key) 530 __GDEF 531 ZCONST uch *h; /* decrypted header */ 532 ZCONST char *key; /* decryption password to test */ 533{ 534 ush b; 535#ifdef ZIP10 536 ush c; 537#endif 538 int n; 539 uch *p; 540 uch hh[RAND_HEAD_LEN]; /* decrypted header */ 541 542 /* set keys and save the encrypted header */ 543 init_keys(__G__ key); 544 memcpy(hh, h, RAND_HEAD_LEN); 545 546 /* check password */ 547 for (n = 0; n < RAND_HEAD_LEN; n++) { 548 zdecode(hh[n]); 549 Trace((stdout, " %02x", hh[n])); 550 } 551 552 Trace((stdout, 553 "\n lrec.crc= %08lx crec.crc= %08lx pInfo->ExtLocHdr= %s\n", 554 GLOBAL(lrec.crc32), GLOBAL(pInfo->crc), 555 GLOBAL(pInfo->ExtLocHdr) ? "true":"false")); 556 Trace((stdout, " incnt = %d unzip offset into zipfile = %ld\n", 557 GLOBAL(incnt), 558 GLOBAL(cur_zipfile_bufstart)+(GLOBAL(inptr)-GLOBAL(inbuf)))); 559 560 /* same test as in zipbare(): */ 561 562#ifdef ZIP10 /* check two bytes */ 563 c = hh[RAND_HEAD_LEN-2], b = hh[RAND_HEAD_LEN-1]; 564 Trace((stdout, 565 " (c | (b<<8)) = %04x (crc >> 16) = %04x lrec.time = %04x\n", 566 (ush)(c | (b<<8)), (ush)(GLOBAL(lrec.crc32) >> 16), 567 ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff)))); 568 if ((ush)(c | (b<<8)) != (GLOBAL(pInfo->ExtLocHdr) ? 569 ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff) : 570 (ush)(GLOBAL(lrec.crc32) >> 16))) 571 return -1; /* bad */ 572#else 573 b = hh[RAND_HEAD_LEN-1]; 574 Trace((stdout, " b = %02x (crc >> 24) = %02x (lrec.time >> 8) = %02x\n", 575 b, (ush)(GLOBAL(lrec.crc32) >> 24), 576 ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff)); 577 if (b != (GLOBAL(pInfo->ExtLocHdr) ? 578 ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff : 579 (ush)(GLOBAL(lrec.crc32) >> 24))) 580 return -1; /* bad */ 581#endif 582 /* password OK: decrypt current buffer contents before leaving */ 583 for (n = (long)GLOBAL(incnt) > GLOBAL(csize) ? 584 (int)GLOBAL(csize) : GLOBAL(incnt), 585 p = GLOBAL(inptr); n--; p++) 586 zdecode(*p); 587 return 0; /* OK */ 588 589} /* end function testkey() */ 590 591#endif /* UNZIP && !FUNZIP */ 592 593#else /* !CRYPT */ 594 595/* something "externally visible" to shut up compiler/linker warnings */ 596int zcr_dummy; 597 598#endif /* ?CRYPT */ 599