Fossil SCM

fossil-scm / compat / zlib / contrib / minizip / crypt.h
Source Blame History 125 lines
7ef7284… drh 1 /* crypt.h -- base code for crypt/uncrypt ZIPfile
7ef7284… drh 2
6ea30fb… florian 3 Copyright (C) 1998-2026 Gilles Vollant
7ef7284… drh 4
7ef7284… drh 5 This code is a modified version of crypting code in Infozip distribution
7ef7284… drh 6
7ef7284… drh 7 The encryption/decryption parts of this source code (as opposed to the
7ef7284… drh 8 non-echoing password parts) were originally written in Europe. The
7ef7284… drh 9 whole source package can be freely distributed, including from the USA.
7ef7284… drh 10 (Prior to January 2000, re-export from the US was a violation of US law.)
7ef7284… drh 11
7ef7284… drh 12 This encryption code is a direct transcription of the algorithm from
7ef7284… drh 13 Roger Schlafly, described by Phil Katz in the file appnote.txt. This
7ef7284… drh 14 file (appnote.txt) is distributed with the PKZIP program (even in the
7ef7284… drh 15 version without encryption capabilities).
7ef7284… drh 16
7ef7284… drh 17 If you don't need crypting in your application, just define symbols
7ef7284… drh 18 NOCRYPT and NOUNCRYPT.
7ef7284… drh 19
7ef7284… drh 20 This code support the "Traditional PKWARE Encryption".
7ef7284… drh 21
7ef7284… drh 22 The new AES encryption added on Zip format by Winzip (see the page
6ea30fb… florian 23 https://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
7ef7284… drh 24 Encryption is not supported.
7ef7284… drh 25 */
7ef7284… drh 26
7ef7284… drh 27 #define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
7ef7284… drh 28
7ef7284… drh 29 /***********************************************************************
7ef7284… drh 30 * Return the next byte in the pseudo-random sequence
7ef7284… drh 31 */
f1f1d6c… drh 32 static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab) {
7ef7284… drh 33 unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
7ef7284… drh 34 * unpredictable manner on 16-bit systems; not a problem
7ef7284… drh 35 * with any known compiler so far, though */
7ef7284… drh 36
adb9e8e… drh 37 (void)pcrc_32_tab;
7ef7284… drh 38 temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
7ef7284… drh 39 return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
7ef7284… drh 40 }
7ef7284… drh 41
7ef7284… drh 42 /***********************************************************************
7ef7284… drh 43 * Update the encryption keys with the next byte of plain text
7ef7284… drh 44 */
f1f1d6c… drh 45 static int update_keys(unsigned long* pkeys, const z_crc_t* pcrc_32_tab, int c) {
7ef7284… drh 46 (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
7ef7284… drh 47 (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
7ef7284… drh 48 (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
7ef7284… drh 49 {
6ea30fb… florian 50 int keyshift = (int)((*(pkeys+1)) >> 24);
7ef7284… drh 51 (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
7ef7284… drh 52 }
7ef7284… drh 53 return c;
7ef7284… drh 54 }
7ef7284… drh 55
7ef7284… drh 56
7ef7284… drh 57 /***********************************************************************
7ef7284… drh 58 * Initialize the encryption keys and the random header according to
7ef7284… drh 59 * the given password.
7ef7284… drh 60 */
f1f1d6c… drh 61 static void init_keys(const char* passwd, unsigned long* pkeys, const z_crc_t* pcrc_32_tab) {
7ef7284… drh 62 *(pkeys+0) = 305419896L;
7ef7284… drh 63 *(pkeys+1) = 591751049L;
7ef7284… drh 64 *(pkeys+2) = 878082192L;
7ef7284… drh 65 while (*passwd != '\0') {
7ef7284… drh 66 update_keys(pkeys,pcrc_32_tab,(int)*passwd);
7ef7284… drh 67 passwd++;
7ef7284… drh 68 }
7ef7284… drh 69 }
7ef7284… drh 70
7ef7284… drh 71 #define zdecode(pkeys,pcrc_32_tab,c) \
7ef7284… drh 72 (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
7ef7284… drh 73
7ef7284… drh 74 #define zencode(pkeys,pcrc_32_tab,c,t) \
adb9e8e… drh 75 (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), (Byte)t^(c))
7ef7284… drh 76
7ef7284… drh 77 #ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
7ef7284… drh 78
7ef7284… drh 79 #define RAND_HEAD_LEN 12
7ef7284… drh 80 /* "last resort" source for second part of crypt seed pattern */
7ef7284… drh 81 # ifndef ZCR_SEED2
a9e589c… florian 82 # define ZCR_SEED2 3141592654UL /* use PI as default pattern */
7ef7284… drh 83 # endif
7ef7284… drh 84
adb9e8e… drh 85 static unsigned crypthead(const char* passwd, /* password string */
adb9e8e… drh 86 unsigned char* buf, /* where to write header */
adb9e8e… drh 87 int bufSize,
adb9e8e… drh 88 unsigned long* pkeys,
adb9e8e… drh 89 const z_crc_t* pcrc_32_tab,
f1f1d6c… drh 90 unsigned long crcForCrypting) {
adb9e8e… drh 91 unsigned n; /* index in random header */
7ef7284… drh 92 int t; /* temporary */
7ef7284… drh 93 int c; /* random byte */
7ef7284… drh 94 unsigned char header[RAND_HEAD_LEN-2]; /* random header */
7ef7284… drh 95 static unsigned calls = 0; /* ensure different random header each time */
7ef7284… drh 96
7ef7284… drh 97 if (bufSize<RAND_HEAD_LEN)
7ef7284… drh 98 return 0;
7ef7284… drh 99
7ef7284… drh 100 /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
7ef7284… drh 101 * output of rand() to get less predictability, since rand() is
7ef7284… drh 102 * often poorly implemented.
7ef7284… drh 103 */
7ef7284… drh 104 if (++calls == 1)
7ef7284… drh 105 {
6ea30fb… florian 106 srand((unsigned)time(NULL) ^ ZCR_SEED2);
7ef7284… drh 107 }
7ef7284… drh 108 init_keys(passwd, pkeys, pcrc_32_tab);
7ef7284… drh 109 for (n = 0; n < RAND_HEAD_LEN-2; n++)
7ef7284… drh 110 {
7ef7284… drh 111 c = (rand() >> 7) & 0xff;
7ef7284… drh 112 header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
7ef7284… drh 113 }
7ef7284… drh 114 /* Encrypt random header (last two bytes is high word of crc) */
7ef7284… drh 115 init_keys(passwd, pkeys, pcrc_32_tab);
7ef7284… drh 116 for (n = 0; n < RAND_HEAD_LEN-2; n++)
7ef7284… drh 117 {
7ef7284… drh 118 buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
7ef7284… drh 119 }
7ef7284… drh 120 buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
7ef7284… drh 121 buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
7ef7284… drh 122 return n;
7ef7284… drh 123 }
7ef7284… drh 124
7ef7284… drh 125 #endif

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button