Commit de2361e72ec68f4ea98f6db2965794b0770a753f
1 parent
180052a2
plop
git-svn-id: http://svn.net-core.org/repos/t-engine4@2143 51575b47-30f0-44d4-a5cc-537603b46e54
Showing
7 changed files
with
1215 additions
and
0 deletions
src/luamd5/des56.c
0 → 100644
1 | + | |
2 | +/* | |
3 | + * Fast implementation of the DES, as described in the Federal Register, | |
4 | + * Vol. 40, No. 52, p. 12134, March 17, 1975. | |
5 | + * | |
6 | + * Stuart Levy, Minnesota Supercomputer Center, April 1988. | |
7 | + * Currently (2007) slevy@ncsa.uiuc.edu | |
8 | + * NCSA, University of Illinois Urbana-Champaign | |
9 | + * | |
10 | + * Calling sequence: | |
11 | + * | |
12 | + * typedef unsigned long keysched[32]; | |
13 | + * | |
14 | + * fsetkey(key, keysched) / * Converts a DES key to a "key schedule" * / | |
15 | + * unsigned char key[8]; | |
16 | + * keysched *ks; | |
17 | + * | |
18 | + * fencrypt(block, decrypt, keysched) / * En/decrypts one 64-bit block * / | |
19 | + * unsigned char block[8]; / * data, en/decrypted in place * / | |
20 | + * int decrypt; / * 0=>encrypt, 1=>decrypt * / | |
21 | + * keysched *ks; / * key schedule, as set by fsetkey * / | |
22 | + * | |
23 | + * Key and data block representation: | |
24 | + * The 56-bit key (bits 1..64 including "parity" bits 8, 16, 24, ..., 64) | |
25 | + * and the 64-bit data block (bits 1..64) | |
26 | + * are each stored in arrays of 8 bytes. | |
27 | + * Following the NBS numbering, the MSB has the bit number 1, so | |
28 | + * key[0] = 128*bit1 + 64*bit2 + ... + 1*bit8, ... through | |
29 | + * key[7] = 128*bit57 + 64*bit58 + ... + 1*bit64. | |
30 | + * In the key, "parity" bits are not checked; their values are ignored. | |
31 | + * | |
32 | +*/ | |
33 | + | |
34 | +/* | |
35 | +=============================================================================== | |
36 | +License | |
37 | + | |
38 | +des56.c is licensed under the terms of the MIT license reproduced below. | |
39 | +This means that des56.c is free software and can be used for both academic | |
40 | +and commercial purposes at absolutely no cost. | |
41 | +=============================================================================== | |
42 | +Copyright (C) 1988 Stuart Levy | |
43 | + | |
44 | +Permission is hereby granted, free of charge, to any person obtaining a copy | |
45 | +of this software and associated documentation files (the "Software"), to deal | |
46 | +in the Software without restriction, including without limitation the rights | |
47 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
48 | +copies of the Software, and to permit persons to whom the Software is | |
49 | +furnished to do so, subject to the following conditions: | |
50 | + | |
51 | +The above copyright notice and this permission notice shall be included in | |
52 | +all copies or substantial portions of the Software. | |
53 | + | |
54 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
55 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
56 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
57 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
58 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
59 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
60 | +THE SOFTWARE. | |
61 | + */ | |
62 | + | |
63 | + | |
64 | +#include "des56.h" | |
65 | + | |
66 | + | |
67 | +/* | |
68 | + * Key schedule generation. | |
69 | + * We begin by pointlessly permuting the 56 useful key bits into | |
70 | + * two groups of 28 bits called C and D. | |
71 | + * bK_C and bK_D are indexed by C and D bit numbers, respectively, | |
72 | + * and give the key bit number (1..64) which should initialize that C/D bit. | |
73 | + * This is the "permuted choice 1" table. | |
74 | + */ | |
75 | + | |
76 | +static tiny bK_C[28] = { | |
77 | + 57, 49, 41, 33, 25, 17, 9, | |
78 | + 1, 58, 50, 42, 34, 26, 18, | |
79 | + 10, 2, 59, 51, 43, 35, 27, | |
80 | + 19, 11, 3, 60, 52, 44, 36, | |
81 | +}; | |
82 | +static tiny bK_D[28] = { | |
83 | + 63, 55, 47, 39, 31, 23, 15, | |
84 | + 7, 62, 54, 46, 38, 30, 22, | |
85 | + 14, 6, 61, 53, 45, 37, 29, | |
86 | + 21, 13, 5, 28, 20, 12, 4, | |
87 | +}; | |
88 | + | |
89 | +/* | |
90 | + * For speed, we invert these, building tables to map groups of | |
91 | + * key bits into the corresponding C and D bits. | |
92 | + * We represent C and D each as 28 contiguous bits right-justified in a | |
93 | + * word, padded on the left with zeros. | |
94 | + * If key byte `i' is said to contain bits Ki,0 (MSB) Ki,1 ... Ki,7 (LSB) | |
95 | + * then | |
96 | + * wC_K4[i][Ki,0 Ki,1 Ki,2 Ki,3] gives the C bits for Ki,0..3, | |
97 | + * wD_K4[i][Ki,0 Ki,1 Ki,2 Ki,3] the corresponding D bits, | |
98 | + * wC_K3[i][Ki,4 Ki,5 Ki,6] the C bits for Ki,4..6, | |
99 | + * and wD_K3[i][Ki,4 Ki,5 Ki,6] the D bits for Ki,4..6. | |
100 | + * Ki,7 is ignored since it is the nominal parity bit. | |
101 | + * We could just use a single table for [i][Ki,0 .. Ki,6] but that | |
102 | + * would take a lot of storage for such a rarely-used function. | |
103 | + */ | |
104 | + | |
105 | +static word32 wC_K4[8][16], wC_K3[8][8]; | |
106 | +static word32 wD_K4[8][16], wD_K3[8][8]; | |
107 | + | |
108 | +/* | |
109 | + * Successive Ci and Di for the sixteen steps in the key schedule are | |
110 | + * created by independent 28-bit left circular shifts on C and D. | |
111 | + * The shift count varies with the step number. | |
112 | + */ | |
113 | +static tiny preshift[16] = { | |
114 | + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, | |
115 | +}; | |
116 | + | |
117 | +/* | |
118 | + * Each step in the key schedule is generated by selecting 48 bits | |
119 | + * (8 groups of 6 bits) from the appropriately shifted Ci and Di. | |
120 | + * bCD_KS, indexed by the key schedule bit number, gives the bit number | |
121 | + * in CD (CD1 = MSB of C, CD28 = LSB of C, CD29 = MSB of D, CD56 = LSB of D) | |
122 | + * which determines that bit of the key schedule. | |
123 | + * Note that only C bits (1..28) appear in the first (upper) 24 bits of | |
124 | + * the key schedule, and D bits (29..56) in the second (lower) 24 bits. | |
125 | + * This is the "permuted-choice-2" table. | |
126 | + */ | |
127 | + | |
128 | +static tiny bCD_KS[48] = { | |
129 | + 14, 17, 11, 24, 1, 5, | |
130 | + 3, 28, 15, 6, 21, 10, | |
131 | + 23, 19, 12, 4, 26, 8, | |
132 | + 16, 7, 27, 20, 13, 2, | |
133 | + 41, 52, 31, 37, 47, 55, | |
134 | + 30, 40, 51, 45, 33, 48, | |
135 | + 44, 49, 39, 56, 34, 53, | |
136 | + 46, 42, 50, 36, 29, 32, | |
137 | +}; | |
138 | + | |
139 | +/* | |
140 | + * We invert bCD_KS into a pair of tables which map groups of 4 | |
141 | + * C or D bits into corresponding key schedule bits. | |
142 | + * We represent each step of the key schedule as 8 groups of 8 bits, | |
143 | + * with the 6 real bits right-justified in each 8-bit group. | |
144 | + * hKS_C4[i][C4i+1 .. C4i+4] gives the bits in the high order (first four) | |
145 | + * key schedule "bytes" which correspond to C bits 4i+1 .. 4i+4. | |
146 | + * lKS_D4[i][D4i+1 .. D4i+4] gives the appropriate bits in the latter (last 4) | |
147 | + * key schedule bytes, from the corresponding D bits. | |
148 | + */ | |
149 | + | |
150 | +static word32 hKS_C4[7][16]; | |
151 | +static word32 lKS_D4[7][16]; | |
152 | + | |
153 | +/* | |
154 | + * Encryption/decryption. | |
155 | + * Before beginning, and after ending, we perform another useless permutation | |
156 | + * on the bits in the data block. | |
157 | + * | |
158 | + * The initial permutation and its inverse, final permutation | |
159 | + * are too simple to need a table for. If we break the input I1 .. I64 into | |
160 | + * 8-bit chunks I0,0 I0,1 ... I0,7 I1,0 I1,1 ... I7,7 | |
161 | + * then the initial permutation sets LR as follows: | |
162 | + * L = I7,1 I6,1 I5,1 ... I0,1 I7,3 I6,3 ... I0,3 I7,5 ... I0,5 I7,7 ... I0,7 | |
163 | + * and | |
164 | + * R = I7,0 I6,0 I5,0 ... I0,0 I7,2 I6,2 ... I0,2 I7,4 ... I0,4 I7,6 ... I0,6 | |
165 | + * | |
166 | + * If we number the bits in the final LR similarly, | |
167 | + * L = L0,0 L0,1 ... L3,7 R = R0,0 R0,1 ... R3,7 | |
168 | + * then the output is | |
169 | + * O = R0,7 L0,7 R1,7 L1,7 ... R3,7 L3,7 R0,6 L0,6 ... L3,6 R0,5 ... R3,0 L3,0 | |
170 | + * | |
171 | + * To speed I => LR shuffling we use an array of 32-bit values indexed by | |
172 | + * 8-bit input bytes. | |
173 | + * wL_I8[ 0 I0,1 0 I0,3 0 I0,5 0 I0,7 ] = the corresponding L bits. | |
174 | + * Other R and L bits are derived from wL_I8 by shifting. | |
175 | + * | |
176 | + * To speed LR => O shuffling, an array of 32-bit values indexed by 4-bit lumps: | |
177 | + * wO_L4[ L0,4 L0,5 L0,6 L0,7 ] = the corresponding high-order 32 O bits. | |
178 | + */ | |
179 | + | |
180 | +static word32 wL_I8[0x55 + 1]; | |
181 | +static word32 wO_L4[16]; | |
182 | + | |
183 | +/* | |
184 | + * Core of encryption/decryption. | |
185 | + * In each key schedule stage, we: | |
186 | + * take 8 overlapping groups of 6 bits each from R | |
187 | + * (the NBS tabulates the bit selections in the E table, | |
188 | + * but it's so simple we just use shifting to get the right bits) | |
189 | + * XOR each group with the corresponding bits from the key schedule | |
190 | + * Use the resulting 6 bits as an index into the appropriate S table | |
191 | + * (there are 8 such tables, one per group of 6 bits) | |
192 | + * Each S entry yields 4 bits. | |
193 | + * The 8 groups of 4 bits are catenated into a 32-bit value. | |
194 | + * Those 32 bits are permuted according to the P table. | |
195 | + * Finally the permuted 32-bit value is XORed with L and becomes | |
196 | + * the R value for the next stage, while the previous R becomes the new L. | |
197 | + * | |
198 | + * Here, we merge the P permutation with the S tables by making the | |
199 | + * S entries be 32-bit masks, already suitably permuted. | |
200 | + * Also, the bits in each six-bit group must be permuted before use as | |
201 | + * an index into the NBS-tabulated S tables. | |
202 | + * We rearrange entries in wPS so that natural bit order can be used. | |
203 | + */ | |
204 | + | |
205 | +static word32 wPS[8][64]; | |
206 | + | |
207 | +static tiny P[32] = { | |
208 | + 16, 7, 20, 21, | |
209 | + 29, 12, 28, 17, | |
210 | + 1, 15, 23, 26, | |
211 | + 5, 18, 31, 10, | |
212 | + 2, 8, 24, 14, | |
213 | + 32, 27, 3, 9, | |
214 | + 19, 13, 30, 6, | |
215 | + 22, 11, 4, 25, | |
216 | +}; | |
217 | + | |
218 | +static tiny S[8][64] = { | |
219 | + { | |
220 | + 14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7, | |
221 | + 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8, | |
222 | + 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0, | |
223 | + 15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13, | |
224 | + }, | |
225 | + | |
226 | + { | |
227 | + 15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10, | |
228 | + 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5, | |
229 | + 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15, | |
230 | + 13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9, | |
231 | + }, | |
232 | + | |
233 | + { | |
234 | + 10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8, | |
235 | + 13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1, | |
236 | + 13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7, | |
237 | + 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12, | |
238 | + }, | |
239 | + | |
240 | + { | |
241 | + 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15, | |
242 | + 13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9, | |
243 | + 10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4, | |
244 | + 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14, | |
245 | + }, | |
246 | + | |
247 | + { | |
248 | + 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9, | |
249 | + 14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6, | |
250 | + 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14, | |
251 | + 11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3, | |
252 | + }, | |
253 | + | |
254 | + { | |
255 | + 12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11, | |
256 | + 10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8, | |
257 | + 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6, | |
258 | + 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13, | |
259 | + }, | |
260 | + | |
261 | + { | |
262 | + 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1, | |
263 | + 13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6, | |
264 | + 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2, | |
265 | + 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12, | |
266 | + }, | |
267 | + | |
268 | + { | |
269 | + 13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7, | |
270 | + 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2, | |
271 | + 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8, | |
272 | + 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11, | |
273 | + }, | |
274 | +}; | |
275 | + | |
276 | +static void buildtables( void ) | |
277 | +{ | |
278 | + register int i, j; | |
279 | + register word32 v; | |
280 | + word32 wC_K[64], wD_K[64]; | |
281 | + word32 hKS_C[28], lKS_D[28]; | |
282 | + int Smap[64]; | |
283 | + word32 wP[32]; | |
284 | + | |
285 | +#if USG | |
286 | +# define ZERO(array) memset((char *)(array), '\0', sizeof(array)) | |
287 | +#else | |
288 | +# if BSD | |
289 | +# define ZERO(array) bzero((char *)(array), sizeof(array)) | |
290 | +# else | |
291 | +# define ZERO(array) { register word32 *p = (word32 *)(array); \ | |
292 | + i = sizeof(array) / sizeof(*p); \ | |
293 | + do { *p++ = 0; } while(--i > 0); \ | |
294 | + } | |
295 | +# endif | |
296 | +#endif | |
297 | + | |
298 | + | |
299 | + /* Invert permuted-choice-1 (key => C,D) */ | |
300 | + | |
301 | + ZERO(wC_K); | |
302 | + ZERO(wD_K); | |
303 | + v = 1; | |
304 | + for(j = 28; --j >= 0; ) { | |
305 | + wC_K[ bK_C[j] - 1 ] = wD_K[ bK_D[j] - 1 ] = v; | |
306 | + v += v; /* (i.e. v <<= 1) */ | |
307 | + } | |
308 | + | |
309 | + for(i = 0; i < 64; i++) { | |
310 | + int t = 8 >> (i & 3); | |
311 | + for(j = 0; j < 16; j++) { | |
312 | + if(j & t) { | |
313 | + wC_K4[i >> 3][j] |= wC_K[i]; | |
314 | + wD_K4[i >> 3][j] |= wD_K[i]; | |
315 | + if(j < 8) { | |
316 | + wC_K3[i >> 3][j] |= wC_K[i + 3]; | |
317 | + wD_K3[i >> 3][j] |= wD_K[i + 3]; | |
318 | + } | |
319 | + } | |
320 | + } | |
321 | + /* Generate the sequence 0,1,2,3, 8,9,10,11, ..., 56,57,58,59. */ | |
322 | + if(t == 1) i += 4; | |
323 | + } | |
324 | + | |
325 | + /* Invert permuted-choice-2 */ | |
326 | + | |
327 | + ZERO(hKS_C); | |
328 | + ZERO(lKS_D); | |
329 | + v = 1; | |
330 | + for(i = 24; (i -= 6) >= 0; ) { | |
331 | + j = i+5; | |
332 | + do { | |
333 | + hKS_C[ bCD_KS[j] - 1 ] = lKS_D[ bCD_KS[j+24] - 28 - 1 ] = v; | |
334 | + v += v; /* Like v <<= 1 but may be faster */ | |
335 | + } while(--j >= i); | |
336 | + v <<= 2; /* Keep byte aligned */ | |
337 | + } | |
338 | + | |
339 | + for(i = 0; i < 28; i++) { | |
340 | + v = 8 >> (i & 3); | |
341 | + for(j = 0; j < 16; j++) { | |
342 | + if(j & v) { | |
343 | + hKS_C4[i >> 2][j] |= hKS_C[i]; | |
344 | + lKS_D4[i >> 2][j] |= lKS_D[i]; | |
345 | + } | |
346 | + } | |
347 | + } | |
348 | + | |
349 | + /* Initial permutation */ | |
350 | + | |
351 | + for(i = 0; i <= 0x55; i++) { | |
352 | + v = 0; | |
353 | + if(i & 64) v = (word32) 1 << 24; | |
354 | + if(i & 16) v |= (word32) 1 << 16; | |
355 | + if(i & 4) v |= (word32) 1 << 8; | |
356 | + if(i & 1) v |= 1; | |
357 | + wL_I8[i] = v; | |
358 | + } | |
359 | + | |
360 | + /* Final permutation */ | |
361 | + | |
362 | + for(i = 0; i < 16; i++) { | |
363 | + v = 0; | |
364 | + if(i & 1) v = (word32) 1 << 24; | |
365 | + if(i & 2) v |= (word32) 1 << 16; | |
366 | + if(i & 4) v |= (word32) 1 << 8; | |
367 | + if(i & 8) v |= (word32) 1; | |
368 | + wO_L4[i] = v; | |
369 | + } | |
370 | + | |
371 | + /* Funny bit rearrangement on second index into S tables */ | |
372 | + | |
373 | + for(i = 0; i < 64; i++) { | |
374 | + Smap[i] = (i & 0x20) | (i & 1) << 4 | (i & 0x1e) >> 1; | |
375 | + } | |
376 | + | |
377 | + /* Invert permutation P into mask indexed by R bit number */ | |
378 | + | |
379 | + v = 1; | |
380 | + for(i = 32; --i >= 0; ) { | |
381 | + wP[ P[i] - 1 ] = v; | |
382 | + v += v; | |
383 | + } | |
384 | + | |
385 | + /* Build bit-mask versions of S tables, indexed in natural bit order */ | |
386 | + | |
387 | + for(i = 0; i < 8; i++) { | |
388 | + for(j = 0; j < 64; j++) { | |
389 | + int k, t; | |
390 | + | |
391 | + t = S[i][ Smap[j] ]; | |
392 | + for(k = 0; k < 4; k++) { | |
393 | + if(t & 8) | |
394 | + wPS[i][j] |= wP[4*i + k]; | |
395 | + t += t; | |
396 | + } | |
397 | + } | |
398 | + } | |
399 | +} | |
400 | + | |
401 | + | |
402 | +void fsetkey(char key[8], keysched *ks) | |
403 | +{ | |
404 | + register int i; | |
405 | + register word32 C, D; | |
406 | + static int built = 0; | |
407 | + | |
408 | + if(!built) { | |
409 | + buildtables(); | |
410 | + built = 1; | |
411 | + } | |
412 | + | |
413 | + C = D = 0; | |
414 | + for(i = 0; i < 8; i++) { | |
415 | + register int v; | |
416 | + | |
417 | + v = key[i] >> 1; /* Discard "parity" bit */ | |
418 | + C |= wC_K4[i][(v>>3) & 15] | wC_K3[i][v & 7]; | |
419 | + D |= wD_K4[i][(v>>3) & 15] | wD_K3[i][v & 7]; | |
420 | + } | |
421 | + | |
422 | + /* | |
423 | + * C and D now hold the suitably right-justified | |
424 | + * 28 permuted key bits each. | |
425 | + */ | |
426 | + for(i = 0; i < 16; i++) { | |
427 | +#ifdef CRAY | |
428 | +#define choice2(x, v) x[6][v&15] | x[5][(v>>4)&15] | x[4][(v>>8)&15] | \ | |
429 | + x[3][(v>>12)&15] | x[2][(v>>16)&15] | x[1][(v>>20)&15] | \ | |
430 | + x[0][(v>>24)&15] | |
431 | +#else | |
432 | + register word32 *ap; | |
433 | + | |
434 | +# define choice2(x, v) ( \ | |
435 | + ap = &(x)[0][0], \ | |
436 | + ap[16*6 + (v&15)] | \ | |
437 | + ap[16*5 + ((v>>4)&15)] | ap[16*4 + ((v>>8)&15)] | \ | |
438 | + ap[16*3 + ((v>>12)&15)] | ap[16*2 + ((v>>16)&15)] | \ | |
439 | + ap[16*1 + ((v>>20)&15)] | ap[16*0 + ((v>>24)&15)] ) | |
440 | +#endif | |
441 | + | |
442 | + | |
443 | + /* 28-bit left circular shift */ | |
444 | + C <<= preshift[i]; | |
445 | + C = ((C >> 28) & 3) | (C & (((word32)1<<28) - 1)); | |
446 | + ks->KS[i].h = choice2(hKS_C4, C); | |
447 | + | |
448 | + D <<= preshift[i]; | |
449 | + D = ((D >> 28) & 3) | (D & (((word32)1<<28) - 1)); | |
450 | + ks->KS[i].l = choice2(lKS_D4, D); | |
451 | + } | |
452 | +} | |
453 | + | |
454 | +void | |
455 | +fencrypt(char block[8], int decrypt, keysched *ks) | |
456 | +{ | |
457 | + int i; | |
458 | + register word32 L, R; | |
459 | + register struct keystage *ksp; | |
460 | + register word32 *ap; | |
461 | + | |
462 | + /* Initial permutation */ | |
463 | + | |
464 | + L = R = 0; | |
465 | + i = 7; | |
466 | + ap = wL_I8; | |
467 | + do { | |
468 | + register int v; | |
469 | + | |
470 | + v = block[i]; /* Could optimize according to ENDIAN */ | |
471 | + L = ap[v & 0x55] | (L << 1); | |
472 | + R = ap[(v >> 1) & 0x55] | (R << 1); | |
473 | + } while(--i >= 0); | |
474 | + | |
475 | + if(decrypt) { | |
476 | + ksp = &ks->KS[15]; | |
477 | + } else { | |
478 | + ksp = &ks->KS[0]; | |
479 | + } | |
480 | + | |
481 | +#ifdef CRAY | |
482 | +# define PS(i,j) wPS[i][j] | |
483 | +#else | |
484 | +# define PS(i,j) ap[64*(i) + (j)] | |
485 | + ap = &wPS[0][0]; | |
486 | +#endif | |
487 | + | |
488 | + i = 16; | |
489 | + do { | |
490 | + register word32 k, tR; | |
491 | + | |
492 | + tR = (R >> 15) | (R << 17); | |
493 | + | |
494 | + k = ksp->h; | |
495 | + L ^= PS(0, ((tR >> 12) ^ (k >> 24)) & 63) | |
496 | + | PS(1, ((tR >> 8) ^ (k >> 16)) & 63) | |
497 | + | PS(2, ((tR >> 4) ^ (k >> 8)) & 63) | |
498 | + | PS(3, (tR ^ k) & 63); | |
499 | + | |
500 | + k = ksp->l; | |
501 | + L ^= PS(4, ((R >> 11) ^ (k >> 24)) & 63) | |
502 | + | PS(5, ((R >> 7) ^ (k >> 16)) & 63) | |
503 | + | PS(6, ((R >> 3) ^ (k >> 8)) & 63) | |
504 | + | PS(7, ((tR >> 16) ^ k) & 63); | |
505 | + | |
506 | + tR = L; | |
507 | + L = R; | |
508 | + R = tR; | |
509 | + | |
510 | + | |
511 | + if(decrypt) | |
512 | + ksp--; | |
513 | + else | |
514 | + ksp++; | |
515 | + } while(--i > 0); | |
516 | + { | |
517 | + register word32 t; | |
518 | + | |
519 | +#ifdef CRAY | |
520 | +# define FP(k) (wO_L4[ (L >> (k)) & 15 ] << 1 | wO_L4[ (R >> (k)) & 15 ]) | |
521 | +#else | |
522 | +# define FP(k) (ap[ (L >> (k)) & 15 ] << 1 | ap[ (R >> (k)) & 15 ]) | |
523 | + | |
524 | + ap = wO_L4; | |
525 | +#endif | |
526 | + | |
527 | + t = FP(0) | (FP(8) | (FP(16) | (FP(24) << 2)) << 2) << 2; | |
528 | + R = FP(4) | (FP(12) | (FP(20) | (FP(28) << 2)) << 2) << 2; | |
529 | + L = t; | |
530 | + } | |
531 | + { | |
532 | + register word32 t; | |
533 | + register char *bp; | |
534 | + | |
535 | + bp = &block[7]; | |
536 | + t = R; | |
537 | + *bp = t & 255; | |
538 | + *--bp = (t >>= 8) & 255; | |
539 | + *--bp = (t >>= 8) & 255; | |
540 | + *--bp = (t >> 8) & 255; | |
541 | + t = L; | |
542 | + *--bp = t & 255; | |
543 | + *--bp = (t >>= 8) & 255; | |
544 | + *--bp = (t >>= 8) & 255; | |
545 | + *--bp = (t >> 8) & 255; | |
546 | + } | |
547 | +} | |
548 | + | ... | ... |
src/luamd5/des56.h
0 → 100644
1 | +#ifndef DES56_H | |
2 | +#define DES56_H 1 | |
3 | +/* | |
4 | + * Fast implementation of the DES, as described in the Federal Register, | |
5 | + * Vol. 40, No. 52, p. 12134, March 17, 1975. | |
6 | + * | |
7 | + * Stuart Levy, Minnesota Supercomputer Center, April 1988. | |
8 | + * Currently (2007) slevy@ncsa.uiuc.edu | |
9 | + * NCSA, University of Illinois Urbana-Champaign | |
10 | + * | |
11 | + * Calling sequence: | |
12 | + * | |
13 | + * typedef unsigned long keysched[32]; | |
14 | + * | |
15 | + * fsetkey(key, keysched) / * Converts a DES key to a "key schedule" * / | |
16 | + * unsigned char key[8]; | |
17 | + * keysched *ks; | |
18 | + * | |
19 | + * fencrypt(block, decrypt, keysched) / * En/decrypts one 64-bit block * / | |
20 | + * unsigned char block[8]; / * data, en/decrypted in place * / | |
21 | + * int decrypt; / * 0=>encrypt, 1=>decrypt * / | |
22 | + * keysched *ks; / * key schedule, as set by fsetkey * / | |
23 | + * | |
24 | + * Key and data block representation: | |
25 | + * The 56-bit key (bits 1..64 including "parity" bits 8, 16, 24, ..., 64) | |
26 | + * and the 64-bit data block (bits 1..64) | |
27 | + * are each stored in arrays of 8 bytes. | |
28 | + * Following the NBS numbering, the MSB has the bit number 1, so | |
29 | + * key[0] = 128*bit1 + 64*bit2 + ... + 1*bit8, ... through | |
30 | + * key[7] = 128*bit57 + 64*bit58 + ... + 1*bit64. | |
31 | + * In the key, "parity" bits are not checked; their values are ignored. | |
32 | + * | |
33 | +*/ | |
34 | + | |
35 | +/* | |
36 | +=============================================================================== | |
37 | +License | |
38 | + | |
39 | +des56.c is licensed under the terms of the MIT license reproduced below. | |
40 | +This means that des56.c is free software and can be used for both academic | |
41 | +and commercial purposes at absolutely no cost. | |
42 | +=============================================================================== | |
43 | +Copyright (C) 1988 Stuart Levy | |
44 | + | |
45 | +Permission is hereby granted, free of charge, to any person obtaining a copy | |
46 | +of this software and associated documentation files (the "Software"), to deal | |
47 | +in the Software without restriction, including without limitation the rights | |
48 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
49 | +copies of the Software, and to permit persons to whom the Software is | |
50 | +furnished to do so, subject to the following conditions: | |
51 | + | |
52 | +The above copyright notice and this permission notice shall be included in | |
53 | +all copies or substantial portions of the Software. | |
54 | + | |
55 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
56 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
57 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
58 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
59 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
60 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
61 | +THE SOFTWARE. | |
62 | + */ | |
63 | + | |
64 | +typedef unsigned long word32; | |
65 | +typedef unsigned char tiny; | |
66 | + | |
67 | +typedef struct keysched { | |
68 | + struct keystage { | |
69 | + word32 h, l; | |
70 | + } KS[16]; | |
71 | +} keysched; | |
72 | + | |
73 | +extern void fsetkey(char key[8], keysched *ks); | |
74 | + | |
75 | +extern void fencrypt(char block[8], int decrypt, keysched *ks); | |
76 | + | |
77 | +#endif /*DES56_H*/ | ... | ... |
src/luamd5/ldes56.c
0 → 100644
1 | +#include <stdlib.h> | |
2 | +#include <string.h> | |
3 | + | |
4 | +#include "des56.h" | |
5 | + | |
6 | +#include "lua.h" | |
7 | +#include "lauxlib.h" | |
8 | + | |
9 | +#include "ldes56.h" | |
10 | + | |
11 | +static int des56_decrypt( lua_State *L ) | |
12 | +{ | |
13 | + char* decypheredText; | |
14 | + keysched KS; | |
15 | + int rel_index, abs_index; | |
16 | + size_t cypherlen; | |
17 | + const char *cypheredText = | |
18 | + luaL_checklstring( L, 1, &cypherlen ); | |
19 | + const char *key = luaL_optstring( L, 2, NULL ); | |
20 | + int padinfo; | |
21 | + | |
22 | + padinfo = cypheredText[cypherlen-1]; | |
23 | + cypherlen--; | |
24 | + | |
25 | + /* Aloca array */ | |
26 | + decypheredText = | |
27 | + (char *) malloc( (cypherlen+1) * sizeof(char)); | |
28 | + if(decypheredText == NULL) { | |
29 | + lua_pushstring(L, "Error decrypting file. Not enough memory."); | |
30 | + lua_error(L); | |
31 | + } | |
32 | + | |
33 | + /* Inicia decifragem */ | |
34 | + if (key && strlen(key) >= 8) | |
35 | + { | |
36 | + char k[8]; | |
37 | + int i; | |
38 | + | |
39 | + for (i=0; i<8; i++) | |
40 | + k[i] = (unsigned char)key[i]; | |
41 | + fsetkey(k, &KS); | |
42 | + } else { | |
43 | + lua_pushstring(L, "Error decrypting file. Invalid key."); | |
44 | + lua_error(L); | |
45 | + } | |
46 | + | |
47 | + rel_index = 0; | |
48 | + abs_index = 0; | |
49 | + | |
50 | + while (abs_index < (int) cypherlen) | |
51 | + { | |
52 | + decypheredText[abs_index] = cypheredText[abs_index]; | |
53 | + abs_index++; | |
54 | + rel_index++; | |
55 | + if( rel_index == 8 ) | |
56 | + { | |
57 | + rel_index = 0; | |
58 | + fencrypt(&(decypheredText[abs_index - 8]), 1, &KS); | |
59 | + } | |
60 | + } | |
61 | + decypheredText[abs_index] = 0; | |
62 | + | |
63 | + lua_pushlstring(L, decypheredText, (abs_index-padinfo)); | |
64 | + free( decypheredText ); | |
65 | + return 1; | |
66 | +} | |
67 | + | |
68 | +static int des56_crypt( lua_State *L ) | |
69 | +{ | |
70 | + char *cypheredText; | |
71 | + keysched KS; | |
72 | + int rel_index, pad, abs_index; | |
73 | + size_t plainlen; | |
74 | + const char *plainText = luaL_checklstring( L, 1, &plainlen ); | |
75 | + const char *key = luaL_optstring( L, 2, NULL ); | |
76 | + | |
77 | + cypheredText = (char *) malloc( (plainlen+8) * sizeof(char)); | |
78 | + if(cypheredText == NULL) { | |
79 | + lua_pushstring(L, "Error encrypting file. Not enough memory."); | |
80 | + lua_error(L); | |
81 | + } | |
82 | + | |
83 | + if (key && strlen(key) >= 8) | |
84 | + { | |
85 | + char k[8]; | |
86 | + int i; | |
87 | + | |
88 | + for (i=0; i<8; i++) | |
89 | + k[i] = (unsigned char)key[i]; | |
90 | + fsetkey(k, &KS); | |
91 | + } else { | |
92 | + lua_pushstring(L, "Error encrypting file. Invalid key."); | |
93 | + lua_error(L); | |
94 | + } | |
95 | + | |
96 | + rel_index = 0; | |
97 | + abs_index = 0; | |
98 | + while (abs_index < (int) plainlen) { | |
99 | + cypheredText[abs_index] = plainText[abs_index]; | |
100 | + abs_index++; | |
101 | + rel_index++; | |
102 | + if( rel_index == 8 ) { | |
103 | + rel_index = 0; | |
104 | + fencrypt(&(cypheredText[abs_index - 8]), 0, &KS); | |
105 | + } | |
106 | + } | |
107 | + | |
108 | + pad = 0; | |
109 | + if(rel_index != 0) { /* Pads remaining bytes with zeroes */ | |
110 | + while(rel_index < 8) | |
111 | + { | |
112 | + pad++; | |
113 | + cypheredText[abs_index++] = 0; | |
114 | + rel_index++; | |
115 | + } | |
116 | + fencrypt(&(cypheredText[abs_index - 8]), 0, &KS); | |
117 | + } | |
118 | + cypheredText[abs_index] = pad; | |
119 | + | |
120 | + lua_pushlstring( L, cypheredText, abs_index+1 ); | |
121 | + free( cypheredText ); | |
122 | + return 1; | |
123 | +} | |
124 | + | |
125 | +/* | |
126 | +** Assumes the table is on top of the stack. | |
127 | +*/ | |
128 | +static void set_info (lua_State *L) { | |
129 | + lua_pushliteral (L, "_COPYRIGHT"); | |
130 | + lua_pushliteral (L, "Copyright (C) 2007 PUC-Rio"); | |
131 | + lua_settable (L, -3); | |
132 | + lua_pushliteral (L, "_DESCRIPTION"); | |
133 | + lua_pushliteral (L, "DES 56 cryptographic facilities for Lua"); | |
134 | + lua_settable (L, -3); | |
135 | + lua_pushliteral (L, "_VERSION"); | |
136 | + lua_pushliteral (L, "DES56 1.1.2"); | |
137 | + lua_settable (L, -3); | |
138 | +} | |
139 | + | |
140 | +static const struct luaL_reg des56lib[] = { | |
141 | + {"crypt", des56_crypt}, | |
142 | + {"decrypt", des56_decrypt}, | |
143 | + {NULL, NULL}, | |
144 | +}; | |
145 | + | |
146 | +int luaopen_des56 (lua_State *L) { | |
147 | + luaL_openlib (L, "des56", des56lib, 0); | |
148 | + set_info (L); | |
149 | + return 1; | |
150 | +} | |
151 | + | |
152 | + | ... | ... |
src/luamd5/ldes56.h
0 → 100644
1 | +int luaopen_des56 (lua_State *L); | ... | ... |
src/luamd5/md5.c
0 → 100644
1 | +/** | |
2 | +* $Id: md5.c,v 1.2 2008/03/24 20:59:12 mascarenhas Exp $ | |
3 | +* Hash function MD5 | |
4 | +* @author Marcela Ozorio Suarez, Roberto I. | |
5 | +*/ | |
6 | + | |
7 | + | |
8 | +#include <string.h> | |
9 | + | |
10 | +#include "md5.h" | |
11 | + | |
12 | + | |
13 | +#define WORD 32 | |
14 | +#define MASK 0xFFFFFFFF | |
15 | +#if __STDC_VERSION__ >= 199901L | |
16 | +#include <stdint.h> | |
17 | +typedef uint32_t WORD32; | |
18 | +#else | |
19 | +typedef unsigned int WORD32; | |
20 | +#endif | |
21 | + | |
22 | + | |
23 | +/** | |
24 | +* md5 hash function. | |
25 | +* @param message: aribtary string. | |
26 | +* @param len: message length. | |
27 | +* @param output: buffer to receive the hash value. Its size must be | |
28 | +* (at least) HASHSIZE. | |
29 | +*/ | |
30 | +void md5 (const char *message, long len, char *output); | |
31 | + | |
32 | + | |
33 | + | |
34 | +/* | |
35 | +** Realiza a rotacao no sentido horario dos bits da variavel 'D' do tipo WORD32. | |
36 | +** Os bits sao deslocados de 'num' posicoes | |
37 | +*/ | |
38 | +#define rotate(D, num) (D<<num) | (D>>(WORD-num)) | |
39 | + | |
40 | +/*Macros que definem operacoes relizadas pelo algoritmo md5 */ | |
41 | +#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z))) | |
42 | +#define G(x, y, z) (((x) & (z)) | ((y) & (~(z)))) | |
43 | +#define H(x, y, z) ((x) ^ (y) ^ (z)) | |
44 | +#define I(x, y, z) ((y) ^ ((x) | (~(z)))) | |
45 | + | |
46 | + | |
47 | +/*vetor de numeros utilizados pelo algoritmo md5 para embaralhar bits */ | |
48 | +static const WORD32 T[64]={ | |
49 | + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, | |
50 | + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, | |
51 | + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, | |
52 | + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, | |
53 | + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, | |
54 | + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, | |
55 | + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, | |
56 | + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, | |
57 | + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, | |
58 | + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, | |
59 | + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, | |
60 | + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, | |
61 | + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, | |
62 | + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, | |
63 | + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, | |
64 | + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 | |
65 | +}; | |
66 | + | |
67 | + | |
68 | +static void word32tobytes (const WORD32 *input, char *output) { | |
69 | + int j = 0; | |
70 | + while (j<4*4) { | |
71 | + WORD32 v = *input++; | |
72 | + output[j++] = (char)(v & 0xff); v >>= 8; | |
73 | + output[j++] = (char)(v & 0xff); v >>= 8; | |
74 | + output[j++] = (char)(v & 0xff); v >>= 8; | |
75 | + output[j++] = (char)(v & 0xff); | |
76 | + } | |
77 | +} | |
78 | + | |
79 | + | |
80 | +static void inic_digest(WORD32 *d) { | |
81 | + d[0] = 0x67452301; | |
82 | + d[1] = 0xEFCDAB89; | |
83 | + d[2] = 0x98BADCFE; | |
84 | + d[3] = 0x10325476; | |
85 | +} | |
86 | + | |
87 | + | |
88 | +/*funcao que implemeta os quatro passos principais do algoritmo MD5 */ | |
89 | +static void digest(const WORD32 *m, WORD32 *d) { | |
90 | + int j; | |
91 | + /*MD5 PASSO1 */ | |
92 | + for (j=0; j<4*4; j+=4) { | |
93 | + d[0] = d[0]+ F(d[1], d[2], d[3])+ m[j] + T[j]; d[0]=rotate(d[0], 7); | |
94 | + d[0]+=d[1]; | |
95 | + d[3] = d[3]+ F(d[0], d[1], d[2])+ m[(j)+1] + T[j+1]; d[3]=rotate(d[3], 12); | |
96 | + d[3]+=d[0]; | |
97 | + d[2] = d[2]+ F(d[3], d[0], d[1])+ m[(j)+2] + T[j+2]; d[2]=rotate(d[2], 17); | |
98 | + d[2]+=d[3]; | |
99 | + d[1] = d[1]+ F(d[2], d[3], d[0])+ m[(j)+3] + T[j+3]; d[1]=rotate(d[1], 22); | |
100 | + d[1]+=d[2]; | |
101 | + } | |
102 | + /*MD5 PASSO2 */ | |
103 | + for (j=0; j<4*4; j+=4) { | |
104 | + d[0] = d[0]+ G(d[1], d[2], d[3])+ m[(5*j+1)&0x0f] + T[(j-1)+17]; | |
105 | + d[0] = rotate(d[0],5); | |
106 | + d[0]+=d[1]; | |
107 | + d[3] = d[3]+ G(d[0], d[1], d[2])+ m[((5*(j+1)+1)&0x0f)] + T[(j+0)+17]; | |
108 | + d[3] = rotate(d[3], 9); | |
109 | + d[3]+=d[0]; | |
110 | + d[2] = d[2]+ G(d[3], d[0], d[1])+ m[((5*(j+2)+1)&0x0f)] + T[(j+1)+17]; | |
111 | + d[2] = rotate(d[2], 14); | |
112 | + d[2]+=d[3]; | |
113 | + d[1] = d[1]+ G(d[2], d[3], d[0])+ m[((5*(j+3)+1)&0x0f)] + T[(j+2)+17]; | |
114 | + d[1] = rotate(d[1], 20); | |
115 | + d[1]+=d[2]; | |
116 | + } | |
117 | + /*MD5 PASSO3 */ | |
118 | + for (j=0; j<4*4; j+=4) { | |
119 | + d[0] = d[0]+ H(d[1], d[2], d[3])+ m[(3*j+5)&0x0f] + T[(j-1)+33]; | |
120 | + d[0] = rotate(d[0], 4); | |
121 | + d[0]+=d[1]; | |
122 | + d[3] = d[3]+ H(d[0], d[1], d[2])+ m[(3*(j+1)+5)&0x0f] + T[(j+0)+33]; | |
123 | + d[3] = rotate(d[3], 11); | |
124 | + d[3]+=d[0]; | |
125 | + d[2] = d[2]+ H(d[3], d[0], d[1])+ m[(3*(j+2)+5)&0x0f] + T[(j+1)+33]; | |
126 | + d[2] = rotate(d[2], 16); | |
127 | + d[2]+=d[3]; | |
128 | + d[1] = d[1]+ H(d[2], d[3], d[0])+ m[(3*(j+3)+5)&0x0f] + T[(j+2)+33]; | |
129 | + d[1] = rotate(d[1], 23); | |
130 | + d[1]+=d[2]; | |
131 | + } | |
132 | + /*MD5 PASSO4 */ | |
133 | + for (j=0; j<4*4; j+=4) { | |
134 | + d[0] = d[0]+ I(d[1], d[2], d[3])+ m[(7*j)&0x0f] + T[(j-1)+49]; | |
135 | + d[0] = rotate(d[0], 6); | |
136 | + d[0]+=d[1]; | |
137 | + d[3] = d[3]+ I(d[0], d[1], d[2])+ m[(7*(j+1))&0x0f] + T[(j+0)+49]; | |
138 | + d[3] = rotate(d[3], 10); | |
139 | + d[3]+=d[0]; | |
140 | + d[2] = d[2]+ I(d[3], d[0], d[1])+ m[(7*(j+2))&0x0f] + T[(j+1)+49]; | |
141 | + d[2] = rotate(d[2], 15); | |
142 | + d[2]+=d[3]; | |
143 | + d[1] = d[1]+ I(d[2], d[3], d[0])+ m[(7*(j+3))&0x0f] + T[(j+2)+49]; | |
144 | + d[1] = rotate(d[1], 21); | |
145 | + d[1]+=d[2]; | |
146 | + } | |
147 | +} | |
148 | + | |
149 | + | |
150 | +static void bytestoword32 (WORD32 *x, const char *pt) { | |
151 | + int i; | |
152 | + for (i=0; i<16; i++) { | |
153 | + int j=i*4; | |
154 | + x[i] = (((WORD32)(unsigned char)pt[j+3] << 8 | | |
155 | + (WORD32)(unsigned char)pt[j+2]) << 8 | | |
156 | + (WORD32)(unsigned char)pt[j+1]) << 8 | | |
157 | + (WORD32)(unsigned char)pt[j]; | |
158 | + } | |
159 | + | |
160 | +} | |
161 | + | |
162 | + | |
163 | +static void put_length(WORD32 *x, long len) { | |
164 | + /* in bits! */ | |
165 | + x[14] = (WORD32)((len<<3) & MASK); | |
166 | + x[15] = (WORD32)(len>>(32-3) & 0x7); | |
167 | +} | |
168 | + | |
169 | + | |
170 | +/* | |
171 | +** returned status: | |
172 | +* 0 - normal message (full 64 bytes) | |
173 | +* 1 - enough room for 0x80, but not for message length (two 4-byte words) | |
174 | +* 2 - enough room for 0x80 plus message length (at least 9 bytes free) | |
175 | +*/ | |
176 | +static int converte (WORD32 *x, const char *pt, int num, int old_status) { | |
177 | + int new_status = 0; | |
178 | + char buff[64]; | |
179 | + if (num<64) { | |
180 | + memcpy(buff, pt, num); /* to avoid changing original string */ | |
181 | + memset(buff+num, 0, 64-num); | |
182 | + if (old_status == 0) | |
183 | + buff[num] = '\200'; | |
184 | + new_status = 1; | |
185 | + pt = buff; | |
186 | + } | |
187 | + bytestoword32(x, pt); | |
188 | + if (num <= (64 - 9)) | |
189 | + new_status = 2; | |
190 | + return new_status; | |
191 | +} | |
192 | + | |
193 | + | |
194 | + | |
195 | +void md5 (const char *message, long len, char *output) { | |
196 | + WORD32 d[4]; | |
197 | + int status = 0; | |
198 | + long i = 0; | |
199 | + inic_digest(d); | |
200 | + while (status != 2) { | |
201 | + WORD32 d_old[4]; | |
202 | + WORD32 wbuff[16]; | |
203 | + int numbytes = (len-i >= 64) ? 64 : len-i; | |
204 | + /*salva os valores do vetor digest*/ | |
205 | + d_old[0]=d[0]; d_old[1]=d[1]; d_old[2]=d[2]; d_old[3]=d[3]; | |
206 | + status = converte(wbuff, message+i, numbytes, status); | |
207 | + if (status == 2) put_length(wbuff, len); | |
208 | + digest(wbuff, d); | |
209 | + d[0]+=d_old[0]; d[1]+=d_old[1]; d[2]+=d_old[2]; d[3]+=d_old[3]; | |
210 | + i += numbytes; | |
211 | + } | |
212 | + word32tobytes(d, output); | |
213 | +} | |
214 | + | ... | ... |
src/luamd5/md5.h
0 → 100644
1 | +/** | |
2 | +* $Id: md5.h,v 1.2 2006/03/03 15:04:49 tomas Exp $ | |
3 | +* Cryptographic module for Lua. | |
4 | +* @author Roberto Ierusalimschy | |
5 | +*/ | |
6 | + | |
7 | + | |
8 | +#ifndef md5_h | |
9 | +#define md5_h | |
10 | + | |
11 | +#include <lua.h> | |
12 | + | |
13 | + | |
14 | +#define HASHSIZE 16 | |
15 | + | |
16 | +void md5 (const char *message, long len, char *output); | |
17 | +int luaopen_md5_core (lua_State *L); | |
18 | + | |
19 | + | |
20 | +#endif | ... | ... |
src/luamd5/md5lib.c
0 → 100644
1 | +/** | |
2 | +* $Id: md5lib.c,v 1.10 2008/05/12 20:51:27 carregal Exp $ | |
3 | +* Cryptographic and Hash functions for Lua | |
4 | +* @author Roberto Ierusalimschy | |
5 | +*/ | |
6 | + | |
7 | + | |
8 | +#include <stdlib.h> | |
9 | +#include <string.h> | |
10 | +#include <time.h> | |
11 | + | |
12 | +#include <lua.h> | |
13 | +#include <lauxlib.h> | |
14 | + | |
15 | +#if ! defined (LUA_VERSION_NUM) || LUA_VERSION_NUM < 501 | |
16 | +#include "compat-5.1.h" | |
17 | +#endif | |
18 | + | |
19 | +#include "md5.h" | |
20 | + | |
21 | + | |
22 | +/** | |
23 | +* Hash function. Returns a hash for a given string. | |
24 | +* @param message: arbitrary binary string. | |
25 | +* @return A 128-bit hash string. | |
26 | +*/ | |
27 | +static int lmd5 (lua_State *L) { | |
28 | + char buff[16]; | |
29 | + size_t l; | |
30 | + const char *message = luaL_checklstring(L, 1, &l); | |
31 | + md5(message, l, buff); | |
32 | + lua_pushlstring(L, buff, 16L); | |
33 | + return 1; | |
34 | +} | |
35 | + | |
36 | + | |
37 | +/** | |
38 | +* X-Or. Does a bit-a-bit exclusive-or of two strings. | |
39 | +* @param s1: arbitrary binary string. | |
40 | +* @param s2: arbitrary binary string with same length as s1. | |
41 | +* @return a binary string with same length as s1 and s2, | |
42 | +* where each bit is the exclusive-or of the corresponding bits in s1-s2. | |
43 | +*/ | |
44 | +static int ex_or (lua_State *L) { | |
45 | + size_t l1, l2; | |
46 | + const char *s1 = luaL_checklstring(L, 1, &l1); | |
47 | + const char *s2 = luaL_checklstring(L, 2, &l2); | |
48 | + luaL_Buffer b; | |
49 | + luaL_argcheck( L, l1 == l2, 2, "lengths must be equal" ); | |
50 | + luaL_buffinit(L, &b); | |
51 | + while (l1--) luaL_putchar(&b, (*s1++)^(*s2++)); | |
52 | + luaL_pushresult(&b); | |
53 | + return 1; | |
54 | +} | |
55 | + | |
56 | + | |
57 | +static void checkseed (lua_State *L) { | |
58 | + if (lua_isnone(L, 3)) { /* no seed? */ | |
59 | + time_t tm = time(NULL); /* for `random' seed */ | |
60 | + lua_pushlstring(L, (char *)&tm, sizeof(tm)); | |
61 | + } | |
62 | +} | |
63 | + | |
64 | + | |
65 | +#define MAXKEY 256 | |
66 | +#define BLOCKSIZE 16 | |
67 | + | |
68 | + | |
69 | + | |
70 | +static int initblock (lua_State *L, const char *seed, int lseed, char *block) { | |
71 | + size_t lkey; | |
72 | + const char *key = luaL_checklstring(L, 2, &lkey); | |
73 | + if (lkey > MAXKEY) | |
74 | + luaL_error(L, "key too long (> %d)", MAXKEY); | |
75 | + memset(block, 0, BLOCKSIZE); | |
76 | + memcpy(block, seed, lseed); | |
77 | + memcpy(block+BLOCKSIZE, key, lkey); | |
78 | + return (int)lkey+BLOCKSIZE; | |
79 | +} | |
80 | + | |
81 | + | |
82 | +static void codestream (lua_State *L, const char *msg, size_t lmsg, | |
83 | + char *block, int lblock) { | |
84 | + luaL_Buffer b; | |
85 | + luaL_buffinit(L, &b); | |
86 | + while (lmsg > 0) { | |
87 | + char code[BLOCKSIZE]; | |
88 | + int i; | |
89 | + md5(block, lblock, code); | |
90 | + for (i=0; i<BLOCKSIZE && lmsg > 0; i++, lmsg--) | |
91 | + code[i] ^= *msg++; | |
92 | + luaL_addlstring(&b, code, i); | |
93 | + memcpy(block, code, i); /* update seed */ | |
94 | + } | |
95 | + luaL_pushresult(&b); | |
96 | +} | |
97 | + | |
98 | + | |
99 | +static void decodestream (lua_State *L, const char *cypher, size_t lcypher, | |
100 | + char *block, int lblock) { | |
101 | + luaL_Buffer b; | |
102 | + luaL_buffinit(L, &b); | |
103 | + while (lcypher > 0) { | |
104 | + char code[BLOCKSIZE]; | |
105 | + int i; | |
106 | + md5(block, lblock, code); /* update seed */ | |
107 | + for (i=0; i<BLOCKSIZE && lcypher > 0; i++, lcypher--) | |
108 | + code[i] ^= *cypher++; | |
109 | + luaL_addlstring(&b, code, i); | |
110 | + memcpy(block, cypher-i, i); | |
111 | + } | |
112 | + luaL_pushresult(&b); | |
113 | +} | |
114 | + | |
115 | + | |
116 | +/** | |
117 | +* Encrypts a string. Uses the hash function md5 in CFB (Cipher-feedback | |
118 | +* mode). | |
119 | +* @param message: arbitrary binary string to be encrypted. | |
120 | +* @param key: arbitrary binary string to be used as a key. | |
121 | +* @param [seed]: optional arbitrary binary string to be used as a seed. | |
122 | +* if no seed is provided, the function uses the result of | |
123 | +* <code>time()</code> as a seed. | |
124 | +* @return The cyphertext (as a binary string). | |
125 | +*/ | |
126 | +static int crypt (lua_State *L) { | |
127 | + size_t lmsg; | |
128 | + const char *msg = luaL_checklstring(L, 1, &lmsg); | |
129 | + size_t lseed; | |
130 | + const char *seed; | |
131 | + int lblock; | |
132 | + char block[BLOCKSIZE+MAXKEY]; | |
133 | + checkseed(L); | |
134 | + seed = luaL_checklstring(L, 3, &lseed); | |
135 | + if (lseed > BLOCKSIZE) | |
136 | + luaL_error(L, "seed too long (> %d)", BLOCKSIZE); | |
137 | + /* put seed and seed length at the beginning of result */ | |
138 | + block[0] = (char)lseed; | |
139 | + memcpy(block+1, seed, lseed); | |
140 | + lua_pushlstring(L, block, lseed+1); /* to concat with result */ | |
141 | + lblock = initblock(L, seed, lseed, block); | |
142 | + codestream(L, msg, lmsg, block, lblock); | |
143 | + lua_concat(L, 2); | |
144 | + return 1; | |
145 | +} | |
146 | + | |
147 | + | |
148 | +/** | |
149 | +* Decrypts a string. For any message, key, and seed, we have that | |
150 | +* <code>decrypt(crypt(msg, key, seed), key) == msg</code>. | |
151 | +* @param cyphertext: message to be decrypted (this must be the result of | |
152 | + a previous call to <code>crypt</code>. | |
153 | +* @param key: arbitrary binary string to be used as a key. | |
154 | +* @return The plaintext. | |
155 | +*/ | |
156 | +static int decrypt (lua_State *L) { | |
157 | + size_t lcyphertext; | |
158 | + const char *cyphertext = luaL_checklstring(L, 1, &lcyphertext); | |
159 | + size_t lseed = cyphertext[0]; | |
160 | + const char *seed = cyphertext+1; | |
161 | + int lblock; | |
162 | + char block[BLOCKSIZE+MAXKEY]; | |
163 | + luaL_argcheck(L, lcyphertext >= lseed+1 && lseed <= BLOCKSIZE, 1, | |
164 | + "invalid cyphered string"); | |
165 | + cyphertext += lseed+1; | |
166 | + lcyphertext -= lseed+1; | |
167 | + lblock = initblock(L, seed, lseed, block); | |
168 | + decodestream(L, cyphertext, lcyphertext, block, lblock); | |
169 | + return 1; | |
170 | +} | |
171 | + | |
172 | + | |
173 | +/* | |
174 | +** Assumes the table is on top of the stack. | |
175 | +*/ | |
176 | +static void set_info (lua_State *L) { | |
177 | + lua_pushliteral (L, "_COPYRIGHT"); | |
178 | + lua_pushliteral (L, "Copyright (C) 2003 PUC-Rio"); | |
179 | + lua_settable (L, -3); | |
180 | + lua_pushliteral (L, "_DESCRIPTION"); | |
181 | + lua_pushliteral (L, "Basic cryptographic facilities"); | |
182 | + lua_settable (L, -3); | |
183 | + lua_pushliteral (L, "_VERSION"); | |
184 | + lua_pushliteral (L, "MD5 1.1.2"); | |
185 | + lua_settable (L, -3); | |
186 | +} | |
187 | + | |
188 | + | |
189 | +static struct luaL_reg md5lib[] = { | |
190 | + {"sum", lmd5}, | |
191 | + {"exor", ex_or}, | |
192 | + {"crypt", crypt}, | |
193 | + {"decrypt", decrypt}, | |
194 | + {NULL, NULL} | |
195 | +}; | |
196 | + | |
197 | + | |
198 | +int luaopen_md5_core (lua_State *L) { | |
199 | + luaL_openlib(L, "md5.core", md5lib, 0); | |
200 | + set_info (L); | |
201 | + return 1; | |
202 | +} | |
203 | + | ... | ... |
-
Please register or login to post a comment