Fix standalone libtasn1.
[shishi.git] / crypto / desCode.h
blobcdb30873ab10a840344a99c1dd522607c566802f
1 /* desCode.h
3 * $Id$ */
5 /* des - fast & portable DES encryption & decryption.
6 * Copyright (C) 1992 Dana L. How
7 * Please see the file `descore.README' for the complete copyright notice.
8 */
10 #include "des.h"
12 /* optional customization:
13 * the idea here is to alter the code so it will still run correctly
14 * on any machine, but the quickest on the specific machine in mind.
15 * note that these silly tweaks can give you a 15%-20% speed improvement
16 * on the sparc -- it's probably even more significant on the 68000. */
18 /* take care of machines with incredibly few registers */
19 #if defined(i386)
20 #define REGISTER /* only x, y, z will be declared register */
21 #else
22 #define REGISTER register
23 #endif /* i386 */
25 /* is auto inc/dec faster than 7bit unsigned indexing? */
26 #if defined(vax) || defined(mc68000)
27 #define FIXR r += 32;
28 #define FIXS s += 8;
29 #define PREV(v,o) *--v
30 #define NEXT(v,o) *v++
31 #else
32 #define FIXR
33 #define FIXS
34 #define PREV(v,o) v[o]
35 #define NEXT(v,o) v[o]
36 #endif
38 /* if no machine type, default is indexing, 6 registers and cheap literals */
39 #if !defined(i386) && !defined(vax) && !defined(mc68000) && !defined(sparc)
40 #define vax
41 #endif
44 /* handle a compiler which can't reallocate registers */
45 /* The BYTE type is used as parameter for the encrypt/decrypt functions.
46 * It's pretty bad to have the function prototypes depend on
47 * a macro definition that the users of the function doesn't
48 * know about. /Niels */
49 #if 0 /* didn't feel like deleting */
50 #define SREGFREE ; s = (uint8_t *) D
51 #define DEST s
52 #define D m0
53 #define BYTE uint32_t
54 #else
55 #define SREGFREE
56 #define DEST d
57 #define D d
58 #define BYTE uint8_t
59 #endif
61 /* handle constants in the optimal way for 386 & vax */
62 /* 386: we declare 3 register variables (see above) and use 3 more variables;
63 * vax: we use 6 variables, all declared register;
64 * we assume address literals are cheap & unrestricted;
65 * we assume immediate constants are cheap & unrestricted. */
66 #if defined(i386) || defined(vax)
67 #define MQ0 des_bigmap
68 #define MQ1 (des_bigmap + 64)
69 #define MQ2 (des_bigmap + 128)
70 #define MQ3 (des_bigmap + 192)
71 #define HQ0(z) /* z |= 0x01000000L; */
72 #define HQ2(z) /* z |= 0x03000200L; */
73 #define LQ0(z) 0xFCFC & z
74 #define LQ1(z) 0xFCFC & z
75 #define LQ2(z) 0xFCFC & z
76 #define LQ3(z) 0xFCFC & z
77 #define SQ 16
78 #define MS0 des_keymap
79 #define MS1 (des_keymap + 64)
80 #define MS2 (des_keymap + 128)
81 #define MS3 (des_keymap + 192)
82 #define MS4 (des_keymap + 256)
83 #define MS5 (des_keymap + 320)
84 #define MS6 (des_keymap + 384)
85 #define MS7 (des_keymap + 448)
86 #define HS(z)
87 #define LS0(z) 0xFC & z
88 #define LS1(z) 0xFC & z
89 #define LS2(z) 0xFC & z
90 #define LS3(z) 0xFC & z
91 #define REGQUICK
92 #define SETQUICK
93 #define REGSMALL
94 #define SETSMALL
95 #endif /* defined(i386) || defined(vax) */
97 /* handle constants in the optimal way for mc68000 */
98 /* in addition to the core 6 variables, we declare 3 registers holding constants
99 * and 4 registers holding address literals.
100 * at most 6 data values and 5 address values are actively used at once.
101 * we assume address literals are so expensive we never use them;
102 * we assume constant index offsets > 127 are expensive, so they are not used.
103 * we assume all constants are expensive and put them in registers,
104 * including shift counts greater than 8. */
105 #if defined(mc68000)
106 #define MQ0 m0
107 #define MQ1 m1
108 #define MQ2 m2
109 #define MQ3 m3
110 #define HQ0(z)
111 #define HQ2(z)
112 #define LQ0(z) k0 & z
113 #define LQ1(z) k0 & z
114 #define LQ2(z) k0 & z
115 #define LQ3(z) k0 & z
116 #define SQ k1
117 #define MS0 m0
118 #define MS1 m0
119 #define MS2 m1
120 #define MS3 m1
121 #define MS4 m2
122 #define MS5 m2
123 #define MS6 m3
124 #define MS7 m3
125 #define HS(z) z |= k0;
126 #define LS0(z) k1 & z
127 #define LS1(z) k2 & z
128 #define LS2(z) k1 & z
129 #define LS3(z) k2 & z
130 #define REGQUICK \
131 register uint32_t k0, k1; \
132 register uint32_t *m0, *m1, *m2, *m3;
133 #define SETQUICK \
134 ; k0 = 0xFCFC \
135 ; k1 = 16 \
136 /*k2 = 28 to speed up ROL */ \
137 ; m0 = des_bigmap \
138 ; m1 = m0 + 64 \
139 ; m2 = m1 + 64 \
140 ; m3 = m2 + 64
141 #define REGSMALL \
142 register uint32_t k0, k1, k2; \
143 register uint32_t *m0, *m1, *m2, *m3;
144 #define SETSMALL \
145 ; k0 = 0x01000100L \
146 ; k1 = 0x0FC \
147 ; k2 = 0x1FC \
148 ; m0 = des_keymap \
149 ; m1 = m0 + 128 \
150 ; m2 = m1 + 128 \
151 ; m3 = m2 + 128
152 #endif /* defined(mc68000) */
154 /* handle constants in the optimal way for sparc */
155 /* in addition to the core 6 variables, we either declare:
156 * 4 registers holding address literals and 1 register holding a constant, or
157 * 8 registers holding address literals.
158 * up to 14 register variables are declared (sparc has %i0-%i5, %l0-%l7).
159 * we assume address literals are so expensive we never use them;
160 * we assume any constant with >10 bits is expensive and put it in a register,
161 * and any other is cheap and is coded in-line. */
162 #if defined(sparc)
163 #define MQ0 m0
164 #define MQ1 m1
165 #define MQ2 m2
166 #define MQ3 m3
167 #define HQ0(z)
168 #define HQ2(z)
169 #define LQ0(z) k0 & z
170 #define LQ1(z) k0 & z
171 #define LQ2(z) k0 & z
172 #define LQ3(z) k0 & z
173 #define SQ 16
174 #define MS0 m0
175 #define MS1 m1
176 #define MS2 m2
177 #define MS3 m3
178 #define MS4 m4
179 #define MS5 m5
180 #define MS6 m6
181 #define MS7 m7
182 #define HS(z)
183 #define LS0(z) 0xFC & z
184 #define LS1(z) 0xFC & z
185 #define LS2(z) 0xFC & z
186 #define LS3(z) 0xFC & z
187 #define REGQUICK \
188 register uint32_t k0; \
189 register uint32_t *m0, *m1, *m2, *m3;
190 #define SETQUICK \
191 ; k0 = 0xFCFC \
192 ; m0 = des_bigmap \
193 ; m1 = m0 + 64 \
194 ; m2 = m1 + 64 \
195 ; m3 = m2 + 64
196 #define REGSMALL \
197 register uint32_t *m0, *m1, *m2, *m3, *m4, *m5, *m6, *m7;
198 #define SETSMALL \
199 ; m0 = des_keymap \
200 ; m1 = m0 + 64 \
201 ; m2 = m1 + 64 \
202 ; m3 = m2 + 64 \
203 ; m4 = m3 + 64 \
204 ; m5 = m4 + 64 \
205 ; m6 = m5 + 64 \
206 ; m7 = m6 + 64
207 #endif /* defined(sparc) */
210 /* some basic stuff */
212 /* generate addresses from a base and an index */
213 /* FIXME: This is used only as *ADD(msi,lsi(z)) or *ADD(mqi,lqi(z)).
214 * Why not use plain indexing instead? /Niels */
215 #define ADD(b,x) (uint32_t *) ((uint8_t *)b + (x))
217 /* low level rotate operations */
218 #define NOP(d,c,o)
219 #define ROL(d,c,o) d = d << c | d >> o
220 #define ROR(d,c,o) d = d >> c | d << o
221 #define ROL1(d) ROL(d, 1, 31)
222 #define ROR1(d) ROR(d, 1, 31)
224 /* elementary swap for doing IP/FP */
225 #define SWAP(x,y,m,b) \
226 z = ((x >> b) ^ y) & m; \
227 x ^= z << b; \
228 y ^= z
231 /* the following macros contain all the important code fragments */
233 /* load input data, then setup special registers holding constants */
234 #define TEMPQUICK(LOAD) \
235 REGQUICK \
236 LOAD() \
237 SETQUICK
238 #define TEMPSMALL(LOAD) \
239 REGSMALL \
240 LOAD() \
241 SETSMALL
243 /* load data */
244 #define LOADDATA(x,y) \
245 FIXS \
246 y = PREV(s, 7); y<<= 8; \
247 y |= PREV(s, 6); y<<= 8; \
248 y |= PREV(s, 5); y<<= 8; \
249 y |= PREV(s, 4); \
250 x = PREV(s, 3); x<<= 8; \
251 x |= PREV(s, 2); x<<= 8; \
252 x |= PREV(s, 1); x<<= 8; \
253 x |= PREV(s, 0) \
254 SREGFREE
255 /* load data without initial permutation and put into efficient position */
256 #define LOADCORE() \
257 LOADDATA(x, y); \
258 ROR1(x); \
259 ROR1(y)
260 /* load data, do the initial permutation and put into efficient position */
261 #define LOADFIPS() \
262 LOADDATA(y, x); \
263 SWAP(x, y, 0x0F0F0F0FL, 004); \
264 SWAP(y, x, 0x0000FFFFL, 020); \
265 SWAP(x, y, 0x33333333L, 002); \
266 SWAP(y, x, 0x00FF00FFL, 010); \
267 ROR1(x); \
268 z = (x ^ y) & 0x55555555L; \
269 y ^= z; \
270 x ^= z; \
271 ROR1(y)
274 /* core encryption/decryption operations */
275 /* S box mapping and P perm */
276 #define KEYMAPSMALL(x,z,mq0,mq1,hq,lq0,lq1,sq,ms0,ms1,ms2,ms3,hs,ls0,ls1,ls2,ls3)\
277 hs(z) \
278 x ^= *ADD(ms3, ls3(z)); \
279 z>>= 8; \
280 x ^= *ADD(ms2, ls2(z)); \
281 z>>= 8; \
282 x ^= *ADD(ms1, ls1(z)); \
283 z>>= 8; \
284 x ^= *ADD(ms0, ls0(z))
285 /* alternate version: use 64k of tables */
286 #define KEYMAPQUICK(x,z,mq0,mq1,hq,lq0,lq1,sq,ms0,ms1,ms2,ms3,hs,ls0,ls1,ls2,ls3)\
287 hq(z) \
288 x ^= *ADD(mq0, lq0(z)); \
289 z>>= sq; \
290 x ^= *ADD(mq1, lq1(z))
291 /* apply 24 key bits and do the odd s boxes */
292 #define S7S1(x,y,z,r,m,KEYMAP,LOAD) \
293 z = LOAD(r, m); \
294 z ^= y; \
295 KEYMAP(x,z,MQ0,MQ1,HQ0,LQ0,LQ1,SQ,MS0,MS1,MS2,MS3,HS,LS0,LS1,LS2,LS3)
296 /* apply 24 key bits and do the even s boxes */
297 #define S6S0(x,y,z,r,m,KEYMAP,LOAD) \
298 z = LOAD(r, m); \
299 z ^= y; \
300 ROL(z, 4, 28); \
301 KEYMAP(x,z,MQ2,MQ3,HQ2,LQ2,LQ3,SQ,MS4,MS5,MS6,MS7,HS,LS0,LS1,LS2,LS3)
302 /* actual iterations. equivalent except for UPDATE & swapping m and n */
303 #define ENCR(x,y,z,r,m,n,KEYMAP) \
304 S7S1(x,y,z,r,m,KEYMAP,NEXT); \
305 S6S0(x,y,z,r,n,KEYMAP,NEXT)
306 #define DECR(x,y,z,r,m,n,KEYMAP) \
307 S6S0(x,y,z,r,m,KEYMAP,PREV); \
308 S7S1(x,y,z,r,n,KEYMAP,PREV)
310 /* write out result in correct byte order */
311 #define SAVEDATA(x,y) \
312 NEXT(DEST, 0) = x; x>>= 8; \
313 NEXT(DEST, 1) = x; x>>= 8; \
314 NEXT(DEST, 2) = x; x>>= 8; \
315 NEXT(DEST, 3) = x; \
316 NEXT(DEST, 4) = y; y>>= 8; \
317 NEXT(DEST, 5) = y; y>>= 8; \
318 NEXT(DEST, 6) = y; y>>= 8; \
319 NEXT(DEST, 7) = y
320 /* write out result */
321 #define SAVECORE() \
322 ROL1(x); \
323 ROL1(y); \
324 SAVEDATA(y, x)
325 /* do final permutation and write out result */
326 #define SAVEFIPS() \
327 ROL1(x); \
328 z = (x ^ y) & 0x55555555L; \
329 y ^= z; \
330 x ^= z; \
331 ROL1(y); \
332 SWAP(x, y, 0x00FF00FFL, 010); \
333 SWAP(y, x, 0x33333333L, 002); \
334 SWAP(x, y, 0x0000FFFFL, 020); \
335 SWAP(y, x, 0x0F0F0F0FL, 004); \
336 SAVEDATA(x, y)
339 /* the following macros contain the encryption/decryption skeletons */
341 #define ENCRYPT(NAME, TEMP, LOAD, KEYMAP, SAVE) \
343 void \
344 NAME(REGISTER BYTE *D, \
345 REGISTER const uint32_t *r, \
346 REGISTER const uint8_t *s) \
348 register uint32_t x, y, z; \
350 /* declare temps & load data */ \
351 TEMP(LOAD); \
353 /* do the 16 iterations */ \
354 ENCR(x,y,z,r, 0, 1,KEYMAP); \
355 ENCR(y,x,z,r, 2, 3,KEYMAP); \
356 ENCR(x,y,z,r, 4, 5,KEYMAP); \
357 ENCR(y,x,z,r, 6, 7,KEYMAP); \
358 ENCR(x,y,z,r, 8, 9,KEYMAP); \
359 ENCR(y,x,z,r,10,11,KEYMAP); \
360 ENCR(x,y,z,r,12,13,KEYMAP); \
361 ENCR(y,x,z,r,14,15,KEYMAP); \
362 ENCR(x,y,z,r,16,17,KEYMAP); \
363 ENCR(y,x,z,r,18,19,KEYMAP); \
364 ENCR(x,y,z,r,20,21,KEYMAP); \
365 ENCR(y,x,z,r,22,23,KEYMAP); \
366 ENCR(x,y,z,r,24,25,KEYMAP); \
367 ENCR(y,x,z,r,26,27,KEYMAP); \
368 ENCR(x,y,z,r,28,29,KEYMAP); \
369 ENCR(y,x,z,r,30,31,KEYMAP); \
371 /* save result */ \
372 SAVE(); \
374 return; \
377 #define DECRYPT(NAME, TEMP, LOAD, KEYMAP, SAVE) \
379 void \
380 NAME(REGISTER BYTE *D, \
381 REGISTER const uint32_t *r, \
382 REGISTER const uint8_t *s) \
384 register uint32_t x, y, z; \
386 /* declare temps & load data */ \
387 TEMP(LOAD); \
389 /* do the 16 iterations */ \
390 FIXR \
391 DECR(x,y,z,r,31,30,KEYMAP); \
392 DECR(y,x,z,r,29,28,KEYMAP); \
393 DECR(x,y,z,r,27,26,KEYMAP); \
394 DECR(y,x,z,r,25,24,KEYMAP); \
395 DECR(x,y,z,r,23,22,KEYMAP); \
396 DECR(y,x,z,r,21,20,KEYMAP); \
397 DECR(x,y,z,r,19,18,KEYMAP); \
398 DECR(y,x,z,r,17,16,KEYMAP); \
399 DECR(x,y,z,r,15,14,KEYMAP); \
400 DECR(y,x,z,r,13,12,KEYMAP); \
401 DECR(x,y,z,r,11,10,KEYMAP); \
402 DECR(y,x,z,r, 9, 8,KEYMAP); \
403 DECR(x,y,z,r, 7, 6,KEYMAP); \
404 DECR(y,x,z,r, 5, 4,KEYMAP); \
405 DECR(x,y,z,r, 3, 2,KEYMAP); \
406 DECR(y,x,z,r, 1, 0,KEYMAP); \
408 /* save result */ \
409 SAVE(); \
411 return; \