beta-0.89.2
[luatex.git] / source / libs / zziplib / zziplib-0.13.62 / docs / zzip-cryptoid.htm
blobee6b120d7f91287b68df2f18da432094c7d04f1c
1 <section> <date> 11. May 2004 </date>
2 <h2> ZIP Ext Encryption </h2> ext/io used for cryptoid plugins
4 <!--border-->
6 <section>
7 <h3> Stronger Obfuscation For ZZip </h3>
9 <P>
10 Some people feel that a simple bytewise xor is not strong enough
11 as an obfuscation for the data. There we have the question how to
12 implant a stronger obfuscation routine to protect that data of an
13 application from artwork theft. Perhaps there is even the idea to
14 use an obfuscation in the range of a real crypt routine - in which
15 case I want to recommend strongly to read the
16 <a href="zzip-crypt.html"> reasoning page </a> why it can not be
17 real encryption and that the resulting obfuscation has an upper
18 limit being <em>lower</em> than the crypt routine complexity.
19 </P>
21 <P>
22 After reminding you of this fact we can go at evaluationg how to
23 implant a stronger obfusction routine to protect your data. The
24 ext/io feature uses a callback routine "read" that must read a
25 block of the given size - for the obfuscation case it will call
26 the "read()" function of the underlying operation system, and
27 the obfuscated block will be deobfuscated before returning it to
28 the caller.
29 </P>
31 <P>
32 In this mechanism there is not asseration at which file-offset
33 the ext/io-read() callback is triggered. That is the reason we
34 have shown obfuscation with bytewise xor-key example - formally
35 this is using obfuscation blocks of 8bit width being aligned
36 on 8bit boundaries in the data file, and our decryption stream
37 is stateless being the same for each obfuscation block (of 8bit
38 width).
39 </P>
40 <P>
41 In order for a stronger obfuscation we have to break those
42 limitations which are directly derived from the natural way
43 of the handling of files by a contemporary operating system.
44 This is triggered as the call synopsis of the ext/io read()
45 callback matches <em>exactly</em> the one of posix, so that
46 one can use the posix read() function reference as the default
47 for ensuring the most minimal overhead in accessing non-obfuscated
48 zip files.
49 <br><small>And btw, the abbreviation "posix" stands for
50 "Portable Open System in Unix".</small>
51 </P>
53 <P>
54 The trick we show here: the first argument of the ext/io read
55 callback is the file descriptor of the underlying operationg
56 system. While we can not add another argument to the ext/io
57 read call we can pick up additional information with the help
58 of that file descriptor id being globally unique even across
59 multiple threads. One solution would make the application map
60 that descriptor id to a special argument but this is often too
61 much overhead: the current file position is enough.
62 </P>
63 <P>
64 The current file position is managed by the operation system
65 via the file descriptor table. There is a function call to
66 map a file descriptor to the current read position offset
67 usually named "tell(fd)". Since this call is not mandated by
68 posix, you can emulate it with the posix lseek() call which
69 returns the resulting offset after the operation was performed,
70 so we just seek by a zero offset: <br><code>
71 <> <> <> <> #define tell(fd) lseek(fd,0,SEEK_CUR)
72 </code>
73 </P>
75 <P>
76 That file offset is measured from the start of the zip archive,
77 not per each zipped file. Remind yourself of that fact when
78 creating your own "zzobfuscate.exe" which should work on the
79 zip archive and not per file before zipping. That is a difference
80 over normal zip archives where the user can atleast recognized the
81 dat file as a zip archive and see a list of files contained in the
82 archive, atleast their names and data start offset.
83 </P>
84 <P>
85 Now, let's use the file read offset to break the blocking
86 limitations of 8bit/8bit to a larger xor-key. In our example
87 we expand to a 32bit/32bit xor-key giving a search space of
88 4<>billion keys instead of the just 256<>keys in 8bit blocking.
89 That is simply done by a static 4<>byte xor-key sequence and using
90 modulo operations for alignment. For the 2^X cases any modulo
91 operations shrink to a set of ultra-fast bitwise-and operations.
92 </P>
94 <pre>
95 static char xor_value[4] = { 0x55, 0x63, 0x27, 0x31 };
96 static zzip_ssize_t xor_read (int f, void* p, zzip_size_t l)
98 zzip_off_t y = tell(f);
99 zzip_size_t r = read(f, p, l);
100 zzip_size_t x; char* q = p;
101 for (x=0; x &lt; r; x++) q[x] ^= xor_value[(y+x)&amp;3];
102 return r;
104 </pre>
106 </section></section>