acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
aaa_crypt.h
1/* crypt.h -- axis code for crypt/uncrypt ZIPfile
2
3
4 Version 1.00, September 10th, 2003
5
6 Copyright (C) 1998-2003 Gilles Vollant
7
8 This code is a modified version of crypting code in Infozip distribution
9
10 The encryption/decryption parts of this source code (as opposed to the
11 non-echoing password parts) were originally written in Europe. The
12 whole source package can be freely distributed, including from the USA.
13 (Prior to January 2000, re-export from the US was a violation of US law.)
14
15 This encryption code is a direct transcription of the algorithm from
16 Roger Schlafly, described by Phil Katz in the file appnote.txt. This
17 file (appnote.txt) is distributed with the PKZIP program (even in the
18 version without encryption capabilities).
19
20 If you don't need crypting in your application, just define symbols
21 NOCRYPT and NOUNCRYPT.
22
23 This code support the "Traditional PKWARE Encryption".
24
25 The aaa_primitive_new AES encryption added on Zip format by Winzip (see the page
26 http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
27 Encryption is not supported.
28*/
29
30#pragma once
31
32#include <time.h>
33
34#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
35
36#define CRC32(ca, b) ((*(pcrc_32_tab+(((::i32)(ca) ^ (b)) & 0xff))) ^ ((ca) >> 8))
37
38/***********************************************************************
39 * Return the next ::u8 in the pseudo-random sequence
40 */
41static ::i32 decrypt_byte(::u32 * pkeys,
42#if defined(WINDOWS) || defined(LINUX)
43 const z_crc_t * pcrc_32_tab
44#else
45 const uLongf * pcrc_32_tab
46#endif
47
48 )
49{
50 ::u32 temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
51 * unpredictable manner on 16-bit systems; not a problem
52 * with any known compiler so far, though */
53
54 temp = ((::u32)(*(pkeys+2)) & 0xffff) | 2;
55 return (::i32)(((temp * (temp ^ 1)) >> 8) & 0xff);
56}
57
58/***********************************************************************
59 * Update the encryption keys with the next ::u8 of plain text
60 */
61#if defined(WINDOWS) || defined(LINUX)
62static ::i32 update_keys(::u32 * pkeys, const z_crc_t * pcrc_32_tab, ::i32 ca)
63#else
64static ::i32 update_keys(::u32 * pkeys, const uLongf * pcrc_32_tab, ::i32 ca)
65#endif
66{
67 (*(pkeys+0)) = (::u32) CRC32((*(pkeys+0)), ca);
68 (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
69 (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
70 {
71 ::i32 keyshift = (::i32)((*(pkeys+1)) >> 24);
72 (*(pkeys+2)) = (::u32) CRC32((*(pkeys+2)), keyshift);
73 }
74 return ca;
75}
76
77
78/***********************************************************************
79 * Initialize the encryption keys and the random header according to
80 * the given password.
81 */
82#if defined(WINDOWS) || defined(LINUX)
83static void init_keys(const_char_pointer passwd, ::u32 * pkeys,const z_crc_t * pcrc_32_tab)
84#else
85static void init_keys(const_char_pointer passwd, ::u32 * pkeys, const uLongf * pcrc_32_tab)
86#endif
87{
88 *(pkeys+0) = 305419896L;
89 *(pkeys+1) = 591751049L;
90 *(pkeys+2) = 878082192L;
91 while (*passwd != '\0')
92 {
93 update_keys(pkeys,pcrc_32_tab,(::i32)*passwd);
94 passwd++;
95 }
96}
97
98#define zdecode(pkeys,pcrc_32_tab,ca) \
99 (update_keys(pkeys,pcrc_32_tab,ca ^= decrypt_byte(pkeys,pcrc_32_tab)))
100
101#define zencode(pkeys,pcrc_32_tab,ca,t) \
102 (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,ca), t^(ca))
103
104#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
105
106#define RAND_HEAD_LEN 12
107/* "last resort" source for element2() part of crypt seed pattern */
108# ifndef ZCR_SEED2
109# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
110# endif
111
112static ::i32 crypthead(
113const_char_pointer passwd, /* password string */
114::u8 * buf, /* where to write header */
115::i32 bufSize,
116::u32 * pkeys,
117#if defined(WINDOWS) || defined(LINUX)
118const z_crc_t * pcrc_32_tab,
119#else
120const uLongf * pcrc_32_tab,
121#endif
122::u32 crcForCrypting)
123{
124 ::i32 n; /* index in random header */
125 ::i32 t; /* temporary */
126 ::i32 ca; /* random ::u8 */
127 uchar header[RAND_HEAD_LEN-2]; /* random header */
128 static ::u32 calls = 0; /* ensure different random header each time */
129
130 if (bufSize<RAND_HEAD_LEN)
131 return 0;
132
133 /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
134 * output of rand() to get less predictability, since rand() is
135 * often poorly implemented.
136 */
137 if (++calls == 1)
138 {
139 srand((::u32)(time(nullptr) ^ ZCR_SEED2));
140 }
141 init_keys(passwd, pkeys, pcrc_32_tab);
142 for (n = 0; n < RAND_HEAD_LEN-2; n++)
143 {
144 ca = (rand() >> 7) & 0xff;
145 header[n] = (uchar)zencode(pkeys, pcrc_32_tab, ca, t);
146 }
147 /* Encrypt random header (last two bytes is high ::u16 of crc) */
148 init_keys(passwd, pkeys, pcrc_32_tab);
149 for (n = 0; n < RAND_HEAD_LEN-2; n++)
150 {
151 buf[n] = (uchar)zencode(pkeys, pcrc_32_tab, header[n], t);
152 }
153 buf[n++] = zencode(pkeys, pcrc_32_tab, (::i32)(crcForCrypting >> 16) & 0xff, t);
154 buf[n++] = zencode(pkeys, pcrc_32_tab, (::i32)(crcForCrypting >> 24) & 0xff, t);
155 return n;
156}
157
158#endif
Definition aaa_time.h:13