2 Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
4 See the accompanying file LICENSE, version 2000-Apr-09 or later
5 (the contents of which are also included in 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
10 cryptf.c (full version) by Info-ZIP. Last revised: [see crypt.h]
11 *** This is only needed to build funzip correctly and is a direct copy
12 of crypt.c. Don't forget to update here if you update crypt.c!! ***
14 This encryption/decryption source code for Info-Zip software was
15 originally written in Europe. The whole source package can be
16 freely distributed, including from the USA. (Prior to January 2000,
17 re-export from the US was a violation of US law.)
19 NOTE on copyright history:
20 Previous versions of this source package (up to version 2.8) were
21 not copyrighted and put in the public domain. If you cannot comply
22 with the Info-Zip LICENSE, you may want to look for one of those
23 public domain versions.
27 This encryption code is a direct transcription of the algorithm from
28 Roger Schlafly, described by Phil Katz in the file appnote.txt. This
29 file (appnote.txt) is distributed with the PKZIP program (even in the
30 version without encryption capabilities).
34 #define ZCRYPT_INTERNAL
46 /* For the encoding task used in Zip (and ZipCloak), we want to initialize
47 the crypt algorithm with some reasonably unpredictable bytes, see
48 the crypthead() function. The standard rand() library function is
49 used to supply these `random' bytes, which in turn is initialized by
50 a srand() call. The srand() function takes an "unsigned" (at least 16bit)
51 seed value as argument to determine the starting point of the rand()
52 pseudo-random number generator.
53 This seed number is constructed as "Seed = Seed1 .XOR. Seed2" with
54 Seed1 supplied by the current time (= "(unsigned)time()") and Seed2
55 as some (hopefully) nondeterministic bitmask. On many (most) systems,
56 we use some "process specific" number, as the PID or something similar,
57 but when nothing unpredictable is available, a fixed number may be
60 1.) This implementation requires the availability of the following
61 standard UNIX C runtime library functions: time(), rand(), srand().
62 On systems where some of them are missing, the environment that
63 incorporates the crypt routines must supply suitable replacement
65 2.) It is a very bad idea to use a second call to time() to set the
66 "Seed2" number! In this case, both "Seed1" and "Seed2" would be
67 (almost) identical, resulting in a (mostly) "zero" constant seed
68 number passed to srand().
70 The implementation environment defined in the "zip.h" header should
71 supply a reasonable definition for ZCR_SEED2 (an unsigned number; for
72 most implementations of rand() and srand(), only the lower 16 bits are
73 significant!). An example that works on many systems would be
74 "#define ZCR_SEED2 (unsigned)getpid()".
75 The default definition for ZCR_SEED2 supplied below should be regarded
76 as a fallback to allow successful compilation in "beta state"
79 # include <time.h> /* time() function supplies first part of crypt seed */
80 /* "last resort" source for second part of crypt seed pattern */
82 # define ZCR_SEED2 (unsigned)3141592654L /* use PI as default pattern */
84 # ifdef GLOBAL /* used in Amiga system headers, maybe others too */
89 # define GLOBAL(g) G.g
94 /* char *key = (char *)NULL; moved to globals.h */
96 local
int testp
OF((__GPRO__ ZCONST uch
*h
));
97 local
int testkey
OF((__GPRO__ ZCONST uch
*h
, ZCONST
char *key
));
101 #ifndef UNZIP /* moved to globals.h for UnZip */
102 local ulg keys
[3]; /* keys defining the pseudo-random sequence */
107 # define Trace(x) fprintf x
114 # define CRC_32_TAB crc_32_tab
117 #define CRC32(c, b) (CRC_32_TAB[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
119 /***********************************************************************
120 * Return the next byte in the pseudo-random sequence
122 int decrypt_byte(__G
)
125 unsigned temp
; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
126 * unpredictable manner on 16-bit systems; not a problem
127 * with any known compiler so far, though */
129 temp
= ((unsigned)GLOBAL(keys
[2]) & 0xffff) | 2;
130 return (int)(((temp
* (temp
^ 1)) >> 8) & 0xff);
133 /***********************************************************************
134 * Update the encryption keys with the next byte of plain text
136 int update_keys(__G__ c
)
138 int c
; /* byte of plain text */
140 GLOBAL(keys
[0]) = CRC32(GLOBAL(keys
[0]), c
);
141 GLOBAL(keys
[1]) += GLOBAL(keys
[0]) & 0xff;
142 GLOBAL(keys
[1]) = GLOBAL(keys
[1]) * 134775813L + 1;
144 register int keyshift
= (int)(GLOBAL(keys
[1]) >> 24);
145 GLOBAL(keys
[2]) = CRC32(GLOBAL(keys
[2]), keyshift
);
151 /***********************************************************************
152 * Initialize the encryption keys and the random header according to
153 * the given password.
155 void init_keys(__G__ passwd
)
157 ZCONST
char *passwd
; /* password string with which to modify keys */
159 GLOBAL(keys
[0]) = 305419896L;
160 GLOBAL(keys
[1]) = 591751049L;
161 GLOBAL(keys
[2]) = 878082192L;
162 while (*passwd
!= '\0') {
163 update_keys(__G__ (int)*passwd
);
171 /***********************************************************************
172 * Write encryption header to file zfile using the password passwd
173 * and the cyclic redundancy check crc.
175 void crypthead(passwd
, crc
, zfile
)
176 ZCONST
char *passwd
; /* password string */
177 ulg crc
; /* crc of file being encrypted */
178 FILE *zfile
; /* where to write header */
180 int n
; /* index in random header */
181 int t
; /* temporary */
182 int c
; /* random byte */
183 int ztemp
; /* temporary for zencoded value */
184 uch header
[RAND_HEAD_LEN
-2]; /* random header */
185 static unsigned calls
= 0; /* ensure different random header each time */
187 /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
188 * output of rand() to get less predictability, since rand() is
189 * often poorly implemented.
192 srand((unsigned)time(NULL
) ^ ZCR_SEED2
);
195 for (n
= 0; n
< RAND_HEAD_LEN
-2; n
++) {
196 c
= (rand() >> 7) & 0xff;
197 header
[n
] = (uch
)zencode(c
, t
);
199 /* Encrypt random header (last two bytes is high word of crc) */
201 for (n
= 0; n
< RAND_HEAD_LEN
-2; n
++) {
202 ztemp
= zencode(header
[n
], t
);
205 ztemp
= zencode((int)(crc
>> 16) & 0xff, t
);
207 ztemp
= zencode((int)(crc
>> 24) & 0xff, t
);
214 /***********************************************************************
215 * Encrypt the zip entry described by z from file source to file dest
216 * using the password passwd. Return an error code in the ZE_ class.
218 int zipcloak(z
, source
, dest
, passwd
)
219 struct zlist far
*z
; /* zip entry to encrypt */
220 FILE *source
, *dest
; /* source and destination files */
221 ZCONST
char *passwd
; /* password string */
223 int c
; /* input byte */
224 int res
; /* result code */
225 ulg n
; /* holds offset and counts size */
226 ush flag
; /* previous flags */
227 int t
; /* temporary */
228 int ztemp
; /* temporary storage for zencode value */
230 /* Set encrypted bit, clear extended local header bit and write local
231 header to output file */
232 if ((n
= (ulg
)ftell(dest
)) == (ulg
)-1L) return ZE_TEMP
;
235 z
->flg
|= 1, z
->flg
&= ~8;
236 z
->lflg
|= 1, z
->lflg
&= ~8;
237 z
->siz
+= RAND_HEAD_LEN
;
238 if ((res
= putlocal(z
, dest
)) != ZE_OK
) return res
;
240 /* Initialize keys with password and write random header */
241 crypthead(passwd
, z
->crc
, dest
);
243 /* Skip local header in input file */
244 if (fseek(source
, (long)(4 + LOCHEAD
+ (ulg
)z
->nam
+ (ulg
)z
->ext
),
246 return ferror(source
) ? ZE_READ
: ZE_EOF
;
250 for (n
= z
->siz
- RAND_HEAD_LEN
; n
; n
--) {
251 if ((c
= getc(source
)) == EOF
) {
252 return ferror(source
) ? ZE_READ
: ZE_EOF
;
254 ztemp
= zencode(c
, t
);
257 /* Skip extended local header in input file if there is one */
258 if ((flag
& 8) != 0 && fseek(source
, 16L, SEEK_CUR
)) {
259 return ferror(source
) ? ZE_READ
: ZE_EOF
;
261 if (fflush(dest
) == EOF
) return ZE_TEMP
;
265 /***********************************************************************
266 * Decrypt the zip entry described by z from file source to file dest
267 * using the password passwd. Return an error code in the ZE_ class.
269 int zipbare(z
, source
, dest
, passwd
)
270 struct zlist far
*z
; /* zip entry to encrypt */
271 FILE *source
, *dest
; /* source and destination files */
272 ZCONST
char *passwd
; /* password string */
274 int c0
, c1
; /* last two input bytes */
275 ulg offset
; /* used for file offsets */
276 ulg size
; /* size of input data */
277 int r
; /* size of encryption header */
278 int res
; /* return code */
279 ush flag
; /* previous flags */
281 /* Save position and skip local header in input file */
282 if ((offset
= (ulg
)ftell(source
)) == (ulg
)-1L ||
283 fseek(source
, (long)(4 + LOCHEAD
+ (ulg
)z
->nam
+ (ulg
)z
->ext
),
285 return ferror(source
) ? ZE_READ
: ZE_EOF
;
287 /* Initialize keys with password */
290 /* Decrypt encryption header, save last two bytes */
292 for (r
= RAND_HEAD_LEN
; r
; r
--) {
294 if ((c1
= getc(source
)) == EOF
) {
295 return ferror(source
) ? ZE_READ
: ZE_EOF
;
297 Trace((stdout
, " (%02x)", c1
));
299 Trace((stdout
, " %02x", c1
));
301 Trace((stdout
, "\n"));
303 /* If last two bytes of header don't match crc (or file time in the
304 * case of an extended local header), back up and just copy. For
305 * pkzip 2.0, the check has been reduced to one byte only.
308 if ((ush
)(c0
| (c1
<<8)) !=
309 (z
->flg
& 8 ? (ush
) z
->tim
& 0xffff : (ush
)(z
->crc
>> 16))) {
311 c0
++; /* avoid warning on unused variable */
312 if ((ush
)c1
!= (z
->flg
& 8 ? (ush
) z
->tim
>> 8 : (ush
)(z
->crc
>> 24))) {
314 if (fseek(source
, offset
, SEEK_SET
)) {
315 return ferror(source
) ? ZE_READ
: ZE_EOF
;
317 if ((res
= zipcopy(z
, source
, dest
)) != ZE_OK
) return res
;
321 /* Clear encrypted bit and local header bit, and write local header to
323 if ((offset
= (ulg
)ftell(dest
)) == (ulg
)-1L) return ZE_TEMP
;
328 z
->siz
-= RAND_HEAD_LEN
;
329 if ((res
= putlocal(z
, dest
)) != ZE_OK
) return res
;
332 for (size
= z
->siz
; size
; size
--) {
333 if ((c1
= getc(source
)) == EOF
) {
334 return ferror(source
) ? ZE_READ
: ZE_EOF
;
339 /* Skip extended local header in input file if there is one */
340 if ((flag
& 8) != 0 && fseek(source
, 16L, SEEK_CUR
)) {
341 return ferror(source
) ? ZE_READ
: ZE_EOF
;
343 if (fflush(dest
) == EOF
) return ZE_TEMP
;
351 /***********************************************************************
352 * If requested, encrypt the data in buf, and in any case call fwrite()
353 * with the arguments to zfwrite(). Return what fwrite() returns.
355 unsigned zfwrite(buf
, item_size
, nb
, f
)
356 zvoid
*buf
; /* data buffer */
357 extent item_size
; /* size of each item in bytes */
358 extent nb
; /* number of items */
359 FILE *f
; /* file to write to */
361 int t
; /* temporary */
363 if (key
!= (char *)NULL
) { /* key is the global password pointer */
364 ulg size
; /* buffer size */
365 char *p
= (char*)buf
; /* steps through buffer */
367 /* Encrypt data in buffer */
368 for (size
= item_size
*(ulg
)nb
; size
!= 0; p
++, size
--) {
369 *p
= (char)zencode(*p
, t
);
372 /* Write the buffer out */
373 return fwrite(buf
, item_size
, nb
, f
);
380 #if (defined(UNZIP) && !defined(FUNZIP))
382 /***********************************************************************
383 * Get the password and set up keys for current zipfile member.
384 * Return PK_ class error.
386 int decrypt(__G__ passwrd
)
388 ZCONST
char *passwrd
;
392 uch h
[RAND_HEAD_LEN
];
394 Trace((stdout
, "\n[incnt = %d]: ", GLOBAL(incnt
)));
396 /* get header once (turn off "encrypted" flag temporarily so we don't
397 * try to decrypt the same data twice) */
398 GLOBAL(pInfo
->encrypted
) = FALSE
;
399 defer_leftover_input(__G
);
400 for (n
= 0; n
< RAND_HEAD_LEN
; n
++) {
403 Trace((stdout
, " (%02x)", h
[n
]));
406 GLOBAL(pInfo
->encrypted
) = TRUE
;
408 if (GLOBAL(newzip
)) { /* this is first encrypted member in this zipfile */
409 GLOBAL(newzip
) = FALSE
;
410 if (passwrd
!= (char *)NULL
) { /* user gave password on command line */
412 if ((GLOBAL(key
) = (char *)malloc(strlen(passwrd
)+1)) ==
415 strcpy(GLOBAL(key
), passwrd
);
416 GLOBAL(nopwd
) = TRUE
; /* inhibit password prompting! */
418 } else if (GLOBAL(key
)) { /* get rid of previous zipfile's key */
420 GLOBAL(key
) = (char *)NULL
;
424 /* if have key already, test it; else allocate memory for it */
427 return PK_COOL
; /* existing password OK (else prompt for new) */
428 else if (GLOBAL(nopwd
))
429 return PK_WARN
; /* user indicated no more prompting */
430 } else if ((GLOBAL(key
) = (char *)malloc(IZ_PWLEN
+1)) == (char *)NULL
)
436 r
= (*G
.decr_passwd
)((zvoid
*)&G
, &n
, GLOBAL(key
), IZ_PWLEN
+1,
437 GLOBAL(zipfn
), GLOBAL(filename
));
438 if (r
== IZ_PW_ERROR
) { /* internal error in fetch of PW */
443 if (r
!= IZ_PW_ENTERED
) { /* user replied "skip" or "skip all" */
444 *GLOBAL(key
) = '\0'; /* We try the NIL password, ... */
445 n
= 0; /* and cancel fetch for this item. */
449 if (r
== IZ_PW_CANCELALL
) /* User replied "Skip all" */
450 GLOBAL(nopwd
) = TRUE
; /* inhibit any further PW prompt! */
455 } /* end function decrypt() */
459 /***********************************************************************
460 * Test the password. Return -1 if bad, 0 if OK.
462 local
int testp(__G__ h
)
467 char *key_translated
;
469 /* On systems with "obscure" native character coding (e.g., EBCDIC),
470 * the first test translates the password to the "main standard"
471 * character coding. */
474 /* allocate buffer for translated password */
475 if ((key_translated
= malloc(strlen(GLOBAL(key
)) + 1)) == (char *)NULL
)
477 /* first try, test password translated "standard" charset */
478 r
= testkey(__G__ h
, STR_TO_CP1(key_translated
, GLOBAL(key
)));
479 #else /* !STR_TO_CP1 */
480 /* first try, test password as supplied on the extractor's host */
481 r
= testkey(__G__ h
, GLOBAL(key
));
482 #endif /* ?STR_TO_CP1 */
487 /* now prepare for second (and maybe third) test with translated pwd */
488 if ((key_translated
= malloc(strlen(GLOBAL(key
)) + 1)) == (char *)NULL
)
491 /* second try, password translated to alternate ("standard") charset */
492 r
= testkey(__G__ h
, STR_TO_CP2(key_translated
, GLOBAL(key
)));
495 /* third try, password translated to another "standard" charset */
496 r
= testkey(__G__ h
, STR_TO_CP3(key_translated
, GLOBAL(key
)));
499 free(key_translated
);
502 #endif /* STR_TO_CP2 */
505 free(key_translated
);
507 /* last resort, test password as supplied on the extractor's host */
508 r
= testkey(__G__ h
, GLOBAL(key
));
510 #endif /* STR_TO_CP1 */
514 } /* end function testp() */
517 local
int testkey(__G__ h
, key
)
519 ZCONST uch
*h
; /* decrypted header */
520 ZCONST
char *key
; /* decryption password to test */
528 uch hh
[RAND_HEAD_LEN
]; /* decrypted header */
530 /* set keys and save the encrypted header */
531 init_keys(__G__ key
);
532 memcpy(hh
, h
, RAND_HEAD_LEN
);
535 for (n
= 0; n
< RAND_HEAD_LEN
; n
++) {
537 Trace((stdout
, " %02x", hh
[n
]));
541 "\n lrec.crc= %08lx crec.crc= %08lx pInfo->ExtLocHdr= %s\n",
542 GLOBAL(lrec
.crc32
), GLOBAL(pInfo
->crc
),
543 GLOBAL(pInfo
->ExtLocHdr
) ? "true":"false"));
544 Trace((stdout
, " incnt = %d unzip offset into zipfile = %ld\n",
546 GLOBAL(cur_zipfile_bufstart
)+(GLOBAL(inptr
)-GLOBAL(inbuf
))));
548 /* same test as in zipbare(): */
550 #ifdef ZIP10 /* check two bytes */
551 c
= hh
[RAND_HEAD_LEN
-2], b
= hh
[RAND_HEAD_LEN
-1];
553 " (c | (b<<8)) = %04x (crc >> 16) = %04x lrec.time = %04x\n",
554 (ush
)(c
| (b
<<8)), (ush
)(GLOBAL(lrec
.crc32
) >> 16),
555 ((ush
)GLOBAL(lrec
.last_mod_dos_datetime
) & 0xffff))));
556 if ((ush
)(c
| (b
<<8)) != (GLOBAL(pInfo
->ExtLocHdr
) ?
557 ((ush
)GLOBAL(lrec
.last_mod_dos_datetime
) & 0xffff) :
558 (ush
)(GLOBAL(lrec
.crc32
) >> 16)))
561 b
= hh
[RAND_HEAD_LEN
-1];
562 Trace((stdout
, " b = %02x (crc >> 24) = %02x (lrec.time >> 8) = %02x\n",
563 b
, (ush
)(GLOBAL(lrec
.crc32
) >> 24),
564 ((ush
)GLOBAL(lrec
.last_mod_dos_datetime
) >> 8) & 0xff));
565 if (b
!= (GLOBAL(pInfo
->ExtLocHdr
) ?
566 ((ush
)GLOBAL(lrec
.last_mod_dos_datetime
) >> 8) & 0xff :
567 (ush
)(GLOBAL(lrec
.crc32
) >> 24)))
570 /* password OK: decrypt current buffer contents before leaving */
571 for (n
= (long)GLOBAL(incnt
) > GLOBAL(csize
) ?
572 (int)GLOBAL(csize
) : GLOBAL(incnt
),
573 p
= GLOBAL(inptr
); n
--; p
++)
577 } /* end function testkey() */
579 #endif /* UNZIP && !FUNZIP */
583 /* something "externally visible" to shut up compiler/linker warnings */