|
|
1.1 root 1: // Except as noted below copyright in this code is held by Dr B.R. Gladman
2: // but free direct or derivative use is permitted subject to acknowledgement
3: // of its origin and subject to any constraints placed on the use of the
4: // algorithm by its designers (if such constraints may exist, this will be
5: // indicated below).
6: //
7: // Dr. B. R. Gladman ( ). 25th January 2000.
8: //
9: // This is an implementation of Serpent, an encryption algorithm designed
10: // by Anderson, Biham and Knudsen and submitted as a candidate for the
11: // Advanced Encryption Standard programme of the US National Institute of
12: // Standards and Technology.
13: //
14: // The designers of Serpent have not placed any constraints on the use of
15: // this algorithm.
16: //
17: // The S box expressions used below are Copyright (C) 2000 Dag Arne Osvik.
18:
19: /* Support for multithreaded operation added by TrueCrypt Foundation */
20:
21: #include "serpent.h"
22:
23: //static u4byte serpent_l_key[140];
24:
25: #define sb0(r0,r1,r2,r3,r4) \
26: __asm { \
27: __asm xor r3,r0 \
28: __asm mov r4,r1 \
29: __asm and r1,r3 \
30: __asm xor r4,r2 \
31: __asm xor r1,r0 \
32: __asm or r0,r3 \
33: __asm xor r0,r4 \
34: __asm xor r4,r3 \
35: __asm xor r3,r2 \
36: __asm or r2,r1 \
37: __asm xor r2,r4 \
38: __asm not r4 \
39: __asm or r4,r1 \
40: __asm xor r1,r3 \
41: __asm xor r1,r4 \
42: __asm or r3,r0 \
43: __asm xor r1,r3 \
44: __asm xor r4,r3 \
45: }
46:
47: #define ib0(r0,r1,r2,r3,r4) \
48: __asm { \
49: __asm not r2 \
50: __asm mov r4,r1 \
51: __asm or r1,r0 \
52: __asm not r4 \
53: __asm xor r1,r2 \
54: __asm or r2,r4 \
55: __asm xor r1,r3 \
56: __asm xor r0,r4 \
57: __asm xor r2,r0 \
58: __asm and r0,r3 \
59: __asm xor r4,r0 \
60: __asm or r0,r1 \
61: __asm xor r0,r2 \
62: __asm xor r3,r4 \
63: __asm xor r2,r1 \
64: __asm xor r3,r0 \
65: __asm xor r3,r1 \
66: __asm and r2,r3 \
67: __asm xor r4,r2 \
68: }
69:
70: #define sb1(r0,r1,r2,r3,r4) \
71: __asm { \
72: __asm not r0 \
73: __asm not r2 \
74: __asm mov r4,r0 \
75: __asm and r0,r1 \
76: __asm xor r2,r0 \
77: __asm or r0,r3 \
78: __asm xor r3,r2 \
79: __asm xor r1,r0 \
80: __asm xor r0,r4 \
81: __asm or r4,r1 \
82: __asm xor r1,r3 \
83: __asm or r2,r0 \
84: __asm and r2,r4 \
85: __asm xor r0,r1 \
86: __asm and r1,r2 \
87: __asm xor r1,r0 \
88: __asm and r0,r2 \
89: __asm xor r0,r4 \
90: }
91:
92: #define ib1(r0,r1,r2,r3,r4) \
93: __asm { \
94: __asm mov r4,r1 \
95: __asm xor r1,r3 \
96: __asm and r3,r1 \
97: __asm xor r4,r2 \
98: __asm xor r3,r0 \
99: __asm or r0,r1 \
100: __asm xor r2,r3 \
101: __asm xor r0,r4 \
102: __asm or r0,r2 \
103: __asm xor r1,r3 \
104: __asm xor r0,r1 \
105: __asm or r1,r3 \
106: __asm xor r1,r0 \
107: __asm not r4 \
108: __asm xor r4,r1 \
109: __asm or r1,r0 \
110: __asm xor r1,r0 \
111: __asm or r1,r4 \
112: __asm xor r3,r1 \
113: }
114:
115: #define sb2(r0,r1,r2,r3,r4) \
116: __asm { \
117: __asm mov r4,r0 \
118: __asm and r0,r2 \
119: __asm xor r0,r3 \
120: __asm xor r2,r1 \
121: __asm xor r2,r0 \
122: __asm or r3,r4 \
123: __asm xor r3,r1 \
124: __asm xor r4,r2 \
125: __asm mov r1,r3 \
126: __asm or r3,r4 \
127: __asm xor r3,r0 \
128: __asm and r0,r1 \
129: __asm xor r4,r0 \
130: __asm xor r1,r3 \
131: __asm xor r1,r4 \
132: __asm not r4 \
133: }
134:
135: #define ib2(r0,r1,r2,r3,r4) \
136: __asm { \
137: __asm xor r2,r3 \
138: __asm xor r3,r0 \
139: __asm mov r4,r3 \
140: __asm and r3,r2 \
141: __asm xor r3,r1 \
142: __asm or r1,r2 \
143: __asm xor r1,r4 \
144: __asm and r4,r3 \
145: __asm xor r2,r3 \
146: __asm and r4,r0 \
147: __asm xor r4,r2 \
148: __asm and r2,r1 \
149: __asm or r2,r0 \
150: __asm not r3 \
151: __asm xor r2,r3 \
152: __asm xor r0,r3 \
153: __asm and r0,r1 \
154: __asm xor r3,r4 \
155: __asm xor r3,r0 \
156: }
157:
158: #define sb3(r0,r1,r2,r3,r4) \
159: __asm { \
160: __asm mov r4,r0 \
161: __asm or r0,r3 \
162: __asm xor r3,r1 \
163: __asm and r1,r4 \
164: __asm xor r4,r2 \
165: __asm xor r2,r3 \
166: __asm and r3,r0 \
167: __asm or r4,r1 \
168: __asm xor r3,r4 \
169: __asm xor r0,r1 \
170: __asm and r4,r0 \
171: __asm xor r1,r3 \
172: __asm xor r4,r2 \
173: __asm or r1,r0 \
174: __asm xor r1,r2 \
175: __asm xor r0,r3 \
176: __asm mov r2,r1 \
177: __asm or r1,r3 \
178: __asm xor r1,r0 \
179: }
180:
181: #define ib3(r0,r1,r2,r3,r4) \
182: __asm { \
183: __asm mov r4,r2 \
184: __asm xor r2,r1 \
185: __asm and r1,r2 \
186: __asm xor r1,r0 \
187: __asm and r0,r4 \
188: __asm xor r4,r3 \
189: __asm or r3,r1 \
190: __asm xor r3,r2 \
191: __asm xor r0,r4 \
192: __asm xor r2,r0 \
193: __asm or r0,r3 \
194: __asm xor r0,r1 \
195: __asm xor r4,r2 \
196: __asm and r2,r3 \
197: __asm or r1,r3 \
198: __asm xor r1,r2 \
199: __asm xor r4,r0 \
200: __asm xor r2,r4 \
201: }
202:
203: #define sb4(r0,r1,r2,r3,r4) \
204: __asm { \
205: __asm xor r1,r3 \
206: __asm not r3 \
207: __asm xor r2,r3 \
208: __asm xor r3,r0 \
209: __asm mov r4,r1 \
210: __asm and r1,r3 \
211: __asm xor r1,r2 \
212: __asm xor r4,r3 \
213: __asm xor r0,r4 \
214: __asm and r2,r4 \
215: __asm xor r2,r0 \
216: __asm and r0,r1 \
217: __asm xor r3,r0 \
218: __asm or r4,r1 \
219: __asm xor r4,r0 \
220: __asm or r0,r3 \
221: __asm xor r0,r2 \
222: __asm and r2,r3 \
223: __asm not r0 \
224: __asm xor r4,r2 \
225: }
226:
227: #define ib4(r0,r1,r2,r3,r4) \
228: __asm { \
229: __asm mov r4,r2 \
230: __asm and r2,r3 \
231: __asm xor r2,r1 \
232: __asm or r1,r3 \
233: __asm and r1,r0 \
234: __asm xor r4,r2 \
235: __asm xor r4,r1 \
236: __asm and r1,r2 \
237: __asm not r0 \
238: __asm xor r3,r4 \
239: __asm xor r1,r3 \
240: __asm and r3,r0 \
241: __asm xor r3,r2 \
242: __asm xor r0,r1 \
243: __asm and r2,r0 \
244: __asm xor r3,r0 \
245: __asm xor r2,r4 \
246: __asm or r2,r3 \
247: __asm xor r3,r0 \
248: __asm xor r2,r1 \
249: }
250:
251: #define sb5(r0,r1,r2,r3,r4) \
252: __asm { \
253: __asm xor r0,r1 \
254: __asm xor r1,r3 \
255: __asm not r3 \
256: __asm mov r4,r1 \
257: __asm and r1,r0 \
258: __asm xor r2,r3 \
259: __asm xor r1,r2 \
260: __asm or r2,r4 \
261: __asm xor r4,r3 \
262: __asm and r3,r1 \
263: __asm xor r3,r0 \
264: __asm xor r4,r1 \
265: __asm xor r4,r2 \
266: __asm xor r2,r0 \
267: __asm and r0,r3 \
268: __asm not r2 \
269: __asm xor r0,r4 \
270: __asm or r4,r3 \
271: __asm xor r2,r4 \
272: }
273:
274: #define ib5(r0,r1,r2,r3,r4) \
275: __asm { \
276: __asm not r1 \
277: __asm mov r4,r3 \
278: __asm xor r2,r1 \
279: __asm or r3,r0 \
280: __asm xor r3,r2 \
281: __asm or r2,r1 \
282: __asm and r2,r0 \
283: __asm xor r4,r3 \
284: __asm xor r2,r4 \
285: __asm or r4,r0 \
286: __asm xor r4,r1 \
287: __asm and r1,r2 \
288: __asm xor r1,r3 \
289: __asm xor r4,r2 \
290: __asm and r3,r4 \
291: __asm xor r4,r1 \
292: __asm xor r3,r0 \
293: __asm xor r3,r4 \
294: __asm not r4 \
295: }
296:
297: #define sb6(r0,r1,r2,r3,r4) \
298: __asm { \
299: __asm not r2 \
300: __asm mov r4,r3 \
301: __asm and r3,r0 \
302: __asm xor r0,r4 \
303: __asm xor r3,r2 \
304: __asm or r2,r4 \
305: __asm xor r1,r3 \
306: __asm xor r2,r0 \
307: __asm or r0,r1 \
308: __asm xor r2,r1 \
309: __asm xor r4,r0 \
310: __asm or r0,r3 \
311: __asm xor r0,r2 \
312: __asm xor r4,r3 \
313: __asm xor r4,r0 \
314: __asm not r3 \
315: __asm and r2,r4 \
316: __asm xor r2,r3 \
317: }
318:
319: #define ib6(r0,r1,r2,r3,r4) \
320: __asm { \
321: __asm xor r0,r2 \
322: __asm mov r4,r2 \
323: __asm and r2,r0 \
324: __asm xor r4,r3 \
325: __asm not r2 \
326: __asm xor r3,r1 \
327: __asm xor r2,r3 \
328: __asm or r4,r0 \
329: __asm xor r0,r2 \
330: __asm xor r3,r4 \
331: __asm xor r4,r1 \
332: __asm and r1,r3 \
333: __asm xor r1,r0 \
334: __asm xor r0,r3 \
335: __asm or r0,r2 \
336: __asm xor r3,r1 \
337: __asm xor r4,r0 \
338: }
339:
340: #define sb7(r0,r1,r2,r3,r4) \
341: __asm { \
342: __asm mov r4,r2 \
343: __asm and r2,r1 \
344: __asm xor r2,r3 \
345: __asm and r3,r1 \
346: __asm xor r4,r2 \
347: __asm xor r2,r1 \
348: __asm xor r1,r0 \
349: __asm or r0,r4 \
350: __asm xor r0,r2 \
351: __asm xor r3,r1 \
352: __asm xor r2,r3 \
353: __asm and r3,r0 \
354: __asm xor r3,r4 \
355: __asm xor r4,r2 \
356: __asm and r2,r0 \
357: __asm not r4 \
358: __asm xor r2,r4 \
359: __asm and r4,r0 \
360: __asm xor r1,r3 \
361: __asm xor r4,r1 \
362: }
363:
364: #define ib7(r0,r1,r2,r3,r4) \
365: __asm { \
366: __asm mov r4,r2 \
367: __asm xor r2,r0 \
368: __asm and r0,r3 \
369: __asm not r2 \
370: __asm or r4,r3 \
371: __asm xor r3,r1 \
372: __asm or r1,r0 \
373: __asm xor r0,r2 \
374: __asm and r2,r4 \
375: __asm xor r1,r2 \
376: __asm xor r2,r0 \
377: __asm or r0,r2 \
378: __asm and r3,r4 \
379: __asm xor r0,r3 \
380: __asm xor r4,r1 \
381: __asm xor r3,r4 \
382: __asm or r4,r0 \
383: __asm xor r3,r2 \
384: __asm xor r4,r2 \
385: }
386:
387: #define f_key(r0,r1,r2,r3) \
388: __asm { \
389: __asm mov r0,[esi] \
390: __asm mov r1,[esi+4] \
391: __asm mov r2,[esi+8] \
392: __asm mov r3,[esi+12] \
393: }
394:
395: #define t_key(r0,r1,r2,r3) \
396: __asm { \
397: __asm mov [esi ],r0 \
398: __asm mov [esi+4],r1 \
399: __asm mov [esi+8],r2 \
400: __asm mov [esi+12],r3 \
401: __asm add esi,16 \
402: }
403:
404: #define f_xor(r0,r1,r2,r3) \
405: __asm { \
406: __asm xor r0,[esi] \
407: __asm xor r1,[esi+4] \
408: __asm xor r2,[esi+8] \
409: __asm xor r3,[esi+12] \
410: __asm add esi,16 \
411: }
412:
413: #define i_xor(r0,r1,r2,r3) \
414: __asm { \
415: __asm sub esi,16 \
416: __asm xor r0,[esi] \
417: __asm xor r1,[esi+4] \
418: __asm xor r2,[esi+8] \
419: __asm xor r3,[esi+12] \
420: }
421:
422: // the linear transformation and its inverse
423:
424: #define rot(r0,r1,r2,r3,r4) \
425: __asm { \
426: __asm rol r0,13 \
427: __asm rol r2,3 \
428: __asm mov r4,r0 \
429: __asm sal r4,3 \
430: __asm xor r3,r2 \
431: __asm xor r3,r4 \
432: __asm xor r1,r0 \
433: __asm xor r1,r2 \
434: __asm rol r1,1 \
435: __asm rol r3,7 \
436: __asm mov r4,r1 \
437: __asm xor r0,r1 \
438: __asm xor r0,r3 \
439: __asm sal r4,7 \
440: __asm xor r2,r3 \
441: __asm xor r2,r4 \
442: __asm rol r0,5 \
443: __asm rol r2,22 \
444: }
445:
446: #define irot(r0,r1,r2,r3,r4) \
447: __asm { \
448: __asm ror r2,22 \
449: __asm ror r0,5 \
450: __asm mov r4,r1 \
451: __asm sal r4,7 \
452: __asm xor r2,r3 \
453: __asm xor r2,r4 \
454: __asm xor r0,r1 \
455: __asm xor r0,r3 \
456: __asm ror r3,7 \
457: __asm mov r4,r0 \
458: __asm ror r1,1 \
459: __asm sal r4,3 \
460: __asm xor r3,r2 \
461: __asm xor r3,r4 \
462: __asm xor r1,r0 \
463: __asm xor r1,r2 \
464: __asm ror r2,3 \
465: __asm ror r0,13 \
466: }
467:
468: char* serpent_name(void)
469: {
470: return "serpent";
471: }
472:
473: // initialise the key schedule from the user supplied key
474:
475: #define k_loop \
476: f_key(eax,ebx,ecx,edx); sb3(eax,ebx,ecx,edx,edi); t_key(ebx,ecx,edx,edi); \
477: f_key(eax,ebx,ecx,edx); sb2(eax,ebx,ecx,edx,edi); t_key(ecx,edx,ebx,edi); \
478: f_key(eax,ebx,ecx,edx); sb1(eax,ebx,ecx,edx,edi); t_key(ecx,eax,edx,ebx); \
479: f_key(eax,ebx,ecx,edx); sb0(eax,ebx,ecx,edx,edi); t_key(ebx,edi,ecx,eax); \
480: f_key(eax,ebx,ecx,edx); sb7(eax,ebx,ecx,edx,edi); t_key(ecx,edi,edx,eax); \
481: f_key(eax,ebx,ecx,edx); sb6(eax,ebx,ecx,edx,edi); t_key(eax,ebx,edi,ecx); \
482: f_key(eax,ebx,ecx,edx); sb5(eax,ebx,ecx,edx,edi); t_key(ebx,edx,eax,ecx); \
483: f_key(eax,ebx,ecx,edx); sb4(eax,ebx,ecx,edx,edi); t_key(ebx,edi,eax,edx);
484:
485: void serpent_set_key(const u1byte in_key[], const u4byte key_len, u1byte *serpent_l_key)
486: {
487: __asm mov edx,key_len
488: __asm cmp edx,256
489: __asm ja short l3
490:
491: #ifdef __cplusplus
492: __asm mov ebx,this
493: __asm lea ebx,[ebx].l_key
494: #else
495: __asm mov ebx,serpent_l_key
496: #endif
497: __asm mov esi,in_key
498: __asm mov ecx,edx
499: __asm add ecx,31
500: __asm sar ecx,5
501: __asm je short l0
502: __asm mov edi,ebx
503: __asm mov eax,ecx
504: __asm rep movsd
505: l0: __asm cmp edx,256
506: __asm je short l1
507: __asm mov ecx,8
508: __asm sub ecx,eax
509: __asm xor eax,eax
510: __asm rep stosd
511: __asm mov ecx,edx
512: __asm mov edx,1
513: __asm sal edx,cl
514: __asm sar ecx,5
515: __asm mov eax,edx
516: __asm dec eax
517: __asm and eax,[ebx+4*ecx]
518: __asm or eax,edx
519: __asm mov [ebx+4*ecx],eax
520: l1: __asm mov esi,ebx
521: __asm mov eax,0x9e3779b9
522: __asm mov ebx,eax
523: __asm xor eax,[esi+ 8]
524: __asm xor ebx,[esi+12]
525: __asm xor eax,[esi+16]
526: __asm xor ebx,[esi+20]
527: __asm xor eax,[esi+24]
528: __asm xor ebx,[esi+28]
529: __asm mov ecx,0
530: __asm push esi
531: l2: __asm mov edx,[esi]
532: __asm xor edx,ecx
533: __asm xor edx,ebx
534: __asm ror edx,21
535: __asm mov [esi+32],edx
536: __asm xor eax,[esi+8]
537: __asm xor eax,edx
538: __asm add esi,4
539: __asm inc ecx
540: __asm mov edx,[esi]
541: __asm xor edx,ecx
542: __asm xor edx,eax
543: __asm ror edx,21
544: __asm mov [esi+32],edx
545: __asm xor ebx,[esi+8]
546: __asm xor ebx,edx
547: __asm add esi,4
548: __asm inc ecx
549: __asm cmp ecx,132
550: __asm jne l2
551: __asm pop esi
552: __asm add esi,4*8
553:
554: k_loop;
555: k_loop;
556: k_loop;
557: k_loop;
558: f_key(eax,ebx,ecx,edx);
559: sb3(eax,ebx,ecx,edx,edi);
560: t_key(ebx,ecx,edx,edi);
561:
562: l3: return;
563: }
564:
565: // encrypt a block of text
566:
567: #define f_loop(a,b,c,d,t) \
568: f_xor(a,b,c,d); sb0(a,b,c,d,t); rot(b,t,c,a,d); \
569: f_xor(b,t,c,a); sb1(b,t,c,a,d); rot(c,b,a,t,d); \
570: f_xor(c,b,a,t); sb2(c,b,a,t,d); rot(a,t,b,d,c); \
571: f_xor(a,t,b,d); sb3(a,t,b,d,c); rot(t,b,d,c,a); \
572: f_xor(t,b,d,c); sb4(t,b,d,c,a); rot(b,a,t,c,d); \
573: f_xor(b,a,t,c); sb5(b,a,t,c,d); rot(a,c,b,t,d); \
574: f_xor(a,c,b,t); sb6(a,c,b,t,d); rot(a,c,d,b,t); \
575: f_xor(a,c,d,b); sb7(a,c,d,b,t);
576:
577: void serpent_encrypt(const u1byte in_blk[16], u1byte out_blk[16], u1byte *serpent_l_key)
578: {
579: __asm mov esi,in_blk
580: __asm mov eax,[esi]
581: __asm mov ebx,[esi+4]
582: __asm mov ecx,[esi+8]
583: __asm mov edx,[esi+12]
584:
585: #ifdef __cplusplus
586: __asm mov esi,this
587: __asm lea esi,[esi].l_key + 4*8
588: #else
589: __asm mov esi,serpent_l_key
590: __asm add esi,4*8
591: #endif
592:
593: f_loop(eax,ebx,ecx,edx,edi); rot(edx,edi,ebx,eax,ecx);
594: f_loop(edx,edi,ebx,eax,ecx); rot(eax,ecx,edi,edx,ebx);
595: f_loop(eax,ecx,edi,edx,ebx); rot(edx,ebx,ecx,eax,edi);
596: f_loop(edx,ebx,ecx,eax,edi); f_xor(eax,edi,ebx,edx);
597:
598: __asm mov esi,out_blk
599: __asm mov [esi],eax
600: __asm mov [esi+4],edi
601: __asm mov [esi+8],ebx
602: __asm mov [esi+12],edx
603: }
604:
605: // decrypt a block of text
606:
607: #define i_loop(a,b,c,d,t) \
608: ib7(a,b,c,d,t); i_xor(d,a,b,t); \
609: irot(d,a,b,t,c); ib6(d,a,b,t,c); i_xor(a,b,c,t); \
610: irot(a,b,c,t,d); ib5(a,b,c,t,d); i_xor(b,d,t,c); \
611: irot(b,d,t,c,a); ib4(b,d,t,c,a); i_xor(b,c,t,a); \
612: irot(b,c,t,a,d); ib3(b,c,t,a,d); i_xor(a,b,t,c); \
613: irot(a,b,t,c,d); ib2(a,b,t,c,d); i_xor(b,d,t,c); \
614: irot(b,d,t,c,a); ib1(b,d,t,c,a); i_xor(a,b,c,t); \
615: irot(a,b,c,t,d); ib0(a,b,c,t,d); i_xor(a,d,b,t);
616:
617: void serpent_decrypt(const u1byte in_blk[16], u1byte out_blk[16], u1byte *serpent_l_key)
618: {
619: __asm mov esi,in_blk
620: __asm mov eax,[esi]
621: __asm mov ebx,[esi+4]
622: __asm mov ecx,[esi+8]
623: __asm mov edx,[esi+12]
624:
625: #ifdef __cplusplus
626: __asm mov esi,this
627: __asm lea esi,[esi].l_key + 4*140
628: #else
629: __asm mov esi,serpent_l_key
630: __asm add esi,4*140
631: #endif
632:
633: i_xor(eax,ebx,ecx,edx); i_loop(eax,ebx,ecx,edx,edi);
634: irot(eax,edx,ebx,edi,ecx); i_loop(eax,edx,ebx,edi,ecx);
635: irot(eax,edi,edx,ecx,ebx); i_loop(eax,edi,edx,ecx,ebx);
636: irot(eax,ecx,edi,ebx,edx); i_loop(eax,ecx,edi,ebx,edx);
637:
638: __asm mov esi,out_blk
639: __asm mov [esi],eax
640: __asm mov [esi+4],ebx
641: __asm mov [esi+8],ecx
642: __asm mov [esi+12],edx
643: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.