23 #if defined(TAOCRYPT_KERNEL_MODE)
24 #define DO_TAOCRYPT_KERNEL_MODE
25 #endif // only some modules now support this
28 #include "runtime.hpp"
33 #include "algorithm.hpp"
37 namespace STL = STL_NAMESPACE;
45 static const byte pc1[] = {
46 57, 49, 41, 33, 25, 17, 9,
47 1, 58, 50, 42, 34, 26, 18,
48 10, 2, 59, 51, 43, 35, 27,
49 19, 11, 3, 60, 52, 44, 36,
51 63, 55, 47, 39, 31, 23, 15,
52 7, 62, 54, 46, 38, 30, 22,
53 14, 6, 61, 53, 45, 37, 29,
54 21, 13, 5, 28, 20, 12, 4
58 static const byte totrot[] = {
59 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
63 static const byte pc2[] = {
68 41, 52, 31, 37, 47, 55,
69 30, 40, 51, 45, 33, 48,
70 44, 49, 39, 56, 34, 53,
71 46, 42, 50, 36, 29, 32
77 static const int bytebit[] = {
78 0200,0100,040,020,010,04,02,01
81 const word32 Spbox[8][64] = {
83 0x01010400,0x00000000,0x00010000,0x01010404,
84 0x01010004,0x00010404,0x00000004,0x00010000,
85 0x00000400,0x01010400,0x01010404,0x00000400,
86 0x01000404,0x01010004,0x01000000,0x00000004,
87 0x00000404,0x01000400,0x01000400,0x00010400,
88 0x00010400,0x01010000,0x01010000,0x01000404,
89 0x00010004,0x01000004,0x01000004,0x00010004,
90 0x00000000,0x00000404,0x00010404,0x01000000,
91 0x00010000,0x01010404,0x00000004,0x01010000,
92 0x01010400,0x01000000,0x01000000,0x00000400,
93 0x01010004,0x00010000,0x00010400,0x01000004,
94 0x00000400,0x00000004,0x01000404,0x00010404,
95 0x01010404,0x00010004,0x01010000,0x01000404,
96 0x01000004,0x00000404,0x00010404,0x01010400,
97 0x00000404,0x01000400,0x01000400,0x00000000,
98 0x00010004,0x00010400,0x00000000,0x01010004},
100 0x80108020,0x80008000,0x00008000,0x00108020,
101 0x00100000,0x00000020,0x80100020,0x80008020,
102 0x80000020,0x80108020,0x80108000,0x80000000,
103 0x80008000,0x00100000,0x00000020,0x80100020,
104 0x00108000,0x00100020,0x80008020,0x00000000,
105 0x80000000,0x00008000,0x00108020,0x80100000,
106 0x00100020,0x80000020,0x00000000,0x00108000,
107 0x00008020,0x80108000,0x80100000,0x00008020,
108 0x00000000,0x00108020,0x80100020,0x00100000,
109 0x80008020,0x80100000,0x80108000,0x00008000,
110 0x80100000,0x80008000,0x00000020,0x80108020,
111 0x00108020,0x00000020,0x00008000,0x80000000,
112 0x00008020,0x80108000,0x00100000,0x80000020,
113 0x00100020,0x80008020,0x80000020,0x00100020,
114 0x00108000,0x00000000,0x80008000,0x00008020,
115 0x80000000,0x80100020,0x80108020,0x00108000},
117 0x00000208,0x08020200,0x00000000,0x08020008,
118 0x08000200,0x00000000,0x00020208,0x08000200,
119 0x00020008,0x08000008,0x08000008,0x00020000,
120 0x08020208,0x00020008,0x08020000,0x00000208,
121 0x08000000,0x00000008,0x08020200,0x00000200,
122 0x00020200,0x08020000,0x08020008,0x00020208,
123 0x08000208,0x00020200,0x00020000,0x08000208,
124 0x00000008,0x08020208,0x00000200,0x08000000,
125 0x08020200,0x08000000,0x00020008,0x00000208,
126 0x00020000,0x08020200,0x08000200,0x00000000,
127 0x00000200,0x00020008,0x08020208,0x08000200,
128 0x08000008,0x00000200,0x00000000,0x08020008,
129 0x08000208,0x00020000,0x08000000,0x08020208,
130 0x00000008,0x00020208,0x00020200,0x08000008,
131 0x08020000,0x08000208,0x00000208,0x08020000,
132 0x00020208,0x00000008,0x08020008,0x00020200},
134 0x00802001,0x00002081,0x00002081,0x00000080,
135 0x00802080,0x00800081,0x00800001,0x00002001,
136 0x00000000,0x00802000,0x00802000,0x00802081,
137 0x00000081,0x00000000,0x00800080,0x00800001,
138 0x00000001,0x00002000,0x00800000,0x00802001,
139 0x00000080,0x00800000,0x00002001,0x00002080,
140 0x00800081,0x00000001,0x00002080,0x00800080,
141 0x00002000,0x00802080,0x00802081,0x00000081,
142 0x00800080,0x00800001,0x00802000,0x00802081,
143 0x00000081,0x00000000,0x00000000,0x00802000,
144 0x00002080,0x00800080,0x00800081,0x00000001,
145 0x00802001,0x00002081,0x00002081,0x00000080,
146 0x00802081,0x00000081,0x00000001,0x00002000,
147 0x00800001,0x00002001,0x00802080,0x00800081,
148 0x00002001,0x00002080,0x00800000,0x00802001,
149 0x00000080,0x00800000,0x00002000,0x00802080},
151 0x00000100,0x02080100,0x02080000,0x42000100,
152 0x00080000,0x00000100,0x40000000,0x02080000,
153 0x40080100,0x00080000,0x02000100,0x40080100,
154 0x42000100,0x42080000,0x00080100,0x40000000,
155 0x02000000,0x40080000,0x40080000,0x00000000,
156 0x40000100,0x42080100,0x42080100,0x02000100,
157 0x42080000,0x40000100,0x00000000,0x42000000,
158 0x02080100,0x02000000,0x42000000,0x00080100,
159 0x00080000,0x42000100,0x00000100,0x02000000,
160 0x40000000,0x02080000,0x42000100,0x40080100,
161 0x02000100,0x40000000,0x42080000,0x02080100,
162 0x40080100,0x00000100,0x02000000,0x42080000,
163 0x42080100,0x00080100,0x42000000,0x42080100,
164 0x02080000,0x00000000,0x40080000,0x42000000,
165 0x00080100,0x02000100,0x40000100,0x00080000,
166 0x00000000,0x40080000,0x02080100,0x40000100},
168 0x20000010,0x20400000,0x00004000,0x20404010,
169 0x20400000,0x00000010,0x20404010,0x00400000,
170 0x20004000,0x00404010,0x00400000,0x20000010,
171 0x00400010,0x20004000,0x20000000,0x00004010,
172 0x00000000,0x00400010,0x20004010,0x00004000,
173 0x00404000,0x20004010,0x00000010,0x20400010,
174 0x20400010,0x00000000,0x00404010,0x20404000,
175 0x00004010,0x00404000,0x20404000,0x20000000,
176 0x20004000,0x00000010,0x20400010,0x00404000,
177 0x20404010,0x00400000,0x00004010,0x20000010,
178 0x00400000,0x20004000,0x20000000,0x00004010,
179 0x20000010,0x20404010,0x00404000,0x20400000,
180 0x00404010,0x20404000,0x00000000,0x20400010,
181 0x00000010,0x00004000,0x20400000,0x00404010,
182 0x00004000,0x00400010,0x20004010,0x00000000,
183 0x20404000,0x20000000,0x00400010,0x20004010},
185 0x00200000,0x04200002,0x04000802,0x00000000,
186 0x00000800,0x04000802,0x00200802,0x04200800,
187 0x04200802,0x00200000,0x00000000,0x04000002,
188 0x00000002,0x04000000,0x04200002,0x00000802,
189 0x04000800,0x00200802,0x00200002,0x04000800,
190 0x04000002,0x04200000,0x04200800,0x00200002,
191 0x04200000,0x00000800,0x00000802,0x04200802,
192 0x00200800,0x00000002,0x04000000,0x00200800,
193 0x04000000,0x00200800,0x00200000,0x04000802,
194 0x04000802,0x04200002,0x04200002,0x00000002,
195 0x00200002,0x04000000,0x04000800,0x00200000,
196 0x04200800,0x00000802,0x00200802,0x04200800,
197 0x00000802,0x04000002,0x04200802,0x04200000,
198 0x00200800,0x00000000,0x00000002,0x04200802,
199 0x00000000,0x00200802,0x04200000,0x00000800,
200 0x04000002,0x04000800,0x00000800,0x00200002},
202 0x10001040,0x00001000,0x00040000,0x10041040,
203 0x10000000,0x10001040,0x00000040,0x10000000,
204 0x00040040,0x10040000,0x10041040,0x00041000,
205 0x10041000,0x00041040,0x00001000,0x00000040,
206 0x10040000,0x10000040,0x10001000,0x00001040,
207 0x00041000,0x00040040,0x10040040,0x10041000,
208 0x00001040,0x00000000,0x00000000,0x10040040,
209 0x10000040,0x10001000,0x00041040,0x00040000,
210 0x00041040,0x00040000,0x10041000,0x00001000,
211 0x00000040,0x10040040,0x00001000,0x00041040,
212 0x10001000,0x00000040,0x10000040,0x10040000,
213 0x10040040,0x10000000,0x00040000,0x10001040,
214 0x00000000,0x10041040,0x00040040,0x10000040,
215 0x10040000,0x10001000,0x10001040,0x00000000,
216 0x10041040,0x00041000,0x00041000,0x00001040,
217 0x00001040,0x00040040,0x10000000,0x10041000}
221 void BasicDES::SetKey(
const byte* key, word32 , CipherDir dir)
223 byte buffer[56+56+8];
224 byte *
const pc1m = buffer;
225 byte *
const pcr = pc1m + 56;
226 byte *
const ks = pcr + 56;
230 for (j = 0; j < 56; j++) {
233 pc1m[j] = (key[l >> 3] &
237 for (i = 0; i < 16; i++) {
239 for (j = 0; j < 56; j++)
240 pcr[j] = pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l: l-28];
242 for (j = 0; j < 48; j++){
244 if (pcr[pc2[j] - 1]){
247 ks[j/6] |= bytebit[l] >> 2;
251 k_[2*
i] = ((word32)ks[0] << 24)
252 | ((word32)ks[2] << 16)
253 | ((word32)ks[4] << 8)
255 k_[2*i + 1] = ((word32)ks[1] << 24)
256 | ((word32)ks[3] << 16)
257 | ((word32)ks[5] << 8)
262 if (dir == DECRYPTION)
263 for (i = 0; i < 16; i += 2) {
264 STL::swap(k_[i], k_[32 - 2 - i]);
265 STL::swap(k_[i+1], k_[32 - 1 - i]);
270 static inline void IPERM(word32& left, word32& right)
274 right = rotlFixed(right, 4
U);
275 work = (left ^ right) & 0xf0f0f0f0;
278 right = rotrFixed(right^work, 20
U);
279 work = (left ^ right) & 0xffff0000;
282 right = rotrFixed(right^work, 18
U);
283 work = (left ^ right) & 0x33333333;
286 right = rotrFixed(right^work, 6
U);
287 work = (left ^ right) & 0x00ff00ff;
290 right = rotlFixed(right^work, 9
U);
291 work = (left ^ right) & 0xaaaaaaaa;
292 left = rotlFixed(left^work, 1
U);
296 static inline void FPERM(word32& left, word32& right)
300 right = rotrFixed(right, 1
U);
301 work = (left ^ right) & 0xaaaaaaaa;
303 left = rotrFixed(left^work, 9
U);
304 work = (left ^ right) & 0x00ff00ff;
306 left = rotlFixed(left^work, 6
U);
307 work = (left ^ right) & 0x33333333;
309 left = rotlFixed(left^work, 18
U);
310 work = (left ^ right) & 0xffff0000;
312 left = rotlFixed(left^work, 20
U);
313 work = (left ^ right) & 0xf0f0f0f0;
315 left = rotrFixed(left^work, 4
U);
319 void BasicDES::RawProcessBlock(word32& lIn, word32& rIn)
const
321 word32 l = lIn, r = rIn;
322 const word32* kptr = k_;
324 for (
unsigned i=0; i<8; i++)
326 word32 work = rotrFixed(r, 4
U) ^ kptr[4*i+0];
327 l ^= Spbox[6][(work) & 0x3f]
328 ^ Spbox[4][(work >> 8) & 0x3f]
329 ^ Spbox[2][(work >> 16) & 0x3f]
330 ^ Spbox[0][(work >> 24) & 0x3f];
331 work = r ^ kptr[4*i+1];
332 l ^= Spbox[7][(work) & 0x3f]
333 ^ Spbox[5][(work >> 8) & 0x3f]
334 ^ Spbox[3][(work >> 16) & 0x3f]
335 ^ Spbox[1][(work >> 24) & 0x3f];
337 work = rotrFixed(l, 4
U) ^ kptr[4*i+2];
338 r ^= Spbox[6][(work) & 0x3f]
339 ^ Spbox[4][(work >> 8) & 0x3f]
340 ^ Spbox[2][(work >> 16) & 0x3f]
341 ^ Spbox[0][(work >> 24) & 0x3f];
342 work = l ^ kptr[4*i+3];
343 r ^= Spbox[7][(work) & 0x3f]
344 ^ Spbox[5][(work >> 8) & 0x3f]
345 ^ Spbox[3][(work >> 16) & 0x3f]
346 ^ Spbox[1][(work >> 24) & 0x3f];
354 typedef BlockGetAndPut<word32, BigEndian> Block;
357 void DES::ProcessAndXorBlock(
const byte* in,
const byte* xOr, byte* out)
const
360 Block::Get(in)(l)(r);
363 RawProcessBlock(l, r);
366 Block::Put(xOr, out)(r)(l);
370 void DES_EDE2::SetKey(
const byte* key, word32 sz, CipherDir dir)
372 des1_.SetKey(key, sz, dir);
373 des2_.SetKey(key + 8, sz, ReverseDir(dir));
377 void DES_EDE2::ProcessAndXorBlock(
const byte* in,
const byte* xOr,
381 Block::Get(in)(l)(r);
384 des1_.RawProcessBlock(l, r);
385 des2_.RawProcessBlock(r, l);
386 des1_.RawProcessBlock(l, r);
389 Block::Put(xOr, out)(r)(l);
393 void DES_EDE3::SetKey(
const byte* key, word32 sz, CipherDir dir)
395 des1_.SetKey(key+(dir==ENCRYPTION?0:2*8), sz, dir);
396 des2_.SetKey(key+8, sz, ReverseDir(dir));
397 des3_.SetKey(key+(dir==DECRYPTION?0:2*8), sz, dir);
402 #if defined(DO_DES_ASM)
405 void DES_EDE3::Process(byte* out,
const byte* in, word32 sz)
408 Mode_BASE::Process(out, in, sz);
412 word32 blocks = sz / DES_BLOCK_SIZE;
415 if (dir_ == ENCRYPTION)
417 r_[0] ^= *(word32*)in;
418 r_[1] ^= *(word32*)(in + 4);
420 AsmProcess((byte*)r_, (byte*)r_, (
void*)Spbox);
422 memcpy(out, r_, DES_BLOCK_SIZE);
424 in += DES_BLOCK_SIZE;
425 out += DES_BLOCK_SIZE;
429 AsmProcess(in, out, (
void*)Spbox);
431 *(word32*)out ^= r_[0];
432 *(word32*)(out + 4) ^= r_[1];
434 memcpy(r_, in, DES_BLOCK_SIZE);
436 out += DES_BLOCK_SIZE;
437 in += DES_BLOCK_SIZE;
441 AsmProcess(in, out, (
void*)Spbox);
443 out += DES_BLOCK_SIZE;
444 in += DES_BLOCK_SIZE;
451 void DES_EDE3::ProcessAndXorBlock(
const byte* in,
const byte* xOr,
455 Block::Get(in)(l)(r);
458 des1_.RawProcessBlock(l, r);
459 des2_.RawProcessBlock(r, l);
460 des3_.RawProcessBlock(l, r);
463 Block::Put(xOr, out)(r)(l);
467 #if defined(DO_DES_ASM)
476 #define AsmIPERM() {\
478 AS2( mov ecx, eax ) \
479 AS2( xor ecx, ebx ) \
480 AS2( and ecx, 0xf0f0f0f0 ) \
481 AS2( xor ebx, ecx ) \
482 AS2( xor eax, ecx ) \
484 AS2( mov ecx, eax ) \
485 AS2( xor ecx, ebx ) \
486 AS2( and ecx, 0xffff0000 ) \
487 AS2( xor ebx, ecx ) \
488 AS2( xor eax, ecx ) \
490 AS2( mov ecx, eax ) \
491 AS2( xor ecx, ebx ) \
492 AS2( and ecx, 0x33333333 ) \
493 AS2( xor ebx, ecx ) \
494 AS2( xor eax, ecx ) \
496 AS2( mov ecx, eax ) \
497 AS2( xor ecx, ebx ) \
498 AS2( and ecx, 0x00ff00ff ) \
499 AS2( xor ebx, ecx ) \
500 AS2( xor eax, ecx ) \
502 AS2( mov ecx, eax ) \
503 AS2( xor ecx, ebx ) \
504 AS2( and ecx, 0xaaaaaaaa ) \
505 AS2( xor eax, ecx ) \
507 AS2( xor ebx, ecx ) }
517 #define AsmFPERM() {\
519 AS2( mov ecx, eax ) \
520 AS2( xor ecx, ebx ) \
521 AS2( and ecx, 0xaaaaaaaa ) \
522 AS2( xor eax, ecx ) \
523 AS2( xor ebx, ecx ) \
525 AS2( mov ecx, ebx ) \
526 AS2( xor ecx, eax ) \
527 AS2( and ecx, 0x00ff00ff ) \
528 AS2( xor eax, ecx ) \
529 AS2( xor ebx, ecx ) \
531 AS2( mov ecx, ebx ) \
532 AS2( xor ecx, eax ) \
533 AS2( and ecx, 0x33333333 ) \
534 AS2( xor eax, ecx ) \
535 AS2( xor ebx, ecx ) \
537 AS2( mov ecx, ebx ) \
538 AS2( xor ecx, eax ) \
539 AS2( and ecx, 0xffff0000 ) \
540 AS2( xor eax, ecx ) \
541 AS2( xor ebx, ecx ) \
543 AS2( mov ecx, ebx ) \
544 AS2( xor ecx, eax ) \
545 AS2( and ecx, 0xf0f0f0f0 ) \
546 AS2( xor eax, ecx ) \
547 AS2( xor ebx, ecx ) \
587 AS2( mov esi, DWORD PTR [edx] )\
590 AS2( and ecx, 0x3f3f3f3f )\
591 AS2( movzx esi, cl )\
592 AS2( movzx edi, ch )\
593 AS2( xor eax, [ebp + esi*4 + 6*256] )\
595 AS2( xor eax, [ebp + edi*4 + 4*256] )\
596 AS2( movzx esi, cl )\
597 AS2( movzx edi, ch )\
598 AS2( xor eax, [ebp + esi*4 + 2*256] )\
599 AS2( mov esi, DWORD PTR [edx + 4] )\
600 AS2( xor eax, [ebp + edi*4] )\
603 AS2( and ecx, 0x3f3f3f3f )\
604 AS2( movzx esi, cl )\
605 AS2( movzx edi, ch )\
606 AS2( xor eax, [ebp + esi*4 + 7*256] )\
608 AS2( xor eax, [ebp + edi*4 + 5*256] )\
609 AS2( movzx esi, cl )\
610 AS2( movzx edi, ch )\
611 AS2( xor eax, [ebp + esi*4 + 3*256] )\
612 AS2( mov esi, DWORD PTR [edx + 8] )\
613 AS2( xor eax, [ebp + edi*4 + 1*256] )\
617 AS2( and ecx, 0x3f3f3f3f )\
618 AS2( movzx esi, cl )\
619 AS2( movzx edi, ch )\
620 AS2( xor ebx, [ebp + esi*4 + 6*256] )\
622 AS2( xor ebx, [ebp + edi*4 + 4*256] )\
623 AS2( movzx esi, cl )\
624 AS2( movzx edi, ch )\
625 AS2( xor ebx, [ebp + esi*4 + 2*256] )\
626 AS2( mov esi, DWORD PTR [edx + 12] )\
627 AS2( xor ebx, [ebp + edi*4] )\
630 AS2( and ecx, 0x3f3f3f3f )\
631 AS2( movzx esi, cl )\
632 AS2( movzx edi, ch )\
633 AS2( xor ebx, [ebp + esi*4 + 7*256] )\
635 AS2( xor ebx, [ebp + edi*4 + 5*256] )\
636 AS2( movzx esi, cl )\
637 AS2( movzx edi, ch )\
638 AS2( xor ebx, [ebp + esi*4 + 3*256] )\
640 AS2( xor ebx, [ebp + edi*4 + 1*256] )
646 void DES_EDE3::AsmProcess(
const byte* in, byte* out,
void* box)
const
649 #define AS1(x) asm(#x);
650 #define AS2(x, y) asm(#x ", " #y);
652 asm(
".intel_syntax noprefix");
655 AS2( movd mm3, edi ) \
656 AS2( movd mm4, ebx ) \
657 AS2( movd mm5, esi ) \
658 AS2( movd mm6, ebp ) \
659 AS2( mov edx, DWORD PTR [ebp + 8] ) \
660 AS2( mov esi, DWORD PTR [ebp + 12] ) \
661 AS2( mov ebp, DWORD PTR [ebp + 20] )
665 AS2( movd edi, mm3 ) \
666 AS2( movd ebx, mm4 ) \
667 AS2( movd esi, mm5 ) \
672 #define AS1(x) __asm x
673 #define AS2(x, y) __asm x, y
677 AS2( mov ebp, esp ) \
678 AS2( movd mm3, edi ) \
679 AS2( movd mm4, ebx ) \
680 AS2( movd mm5, esi ) \
681 AS2( movd mm6, ebp ) \
682 AS2( mov esi, DWORD PTR [ebp + 8] ) \
683 AS2( mov edx, ecx ) \
684 AS2( mov ebp, DWORD PTR [ebp + 16] )
688 AS2( movd edi, mm3 ) \
689 AS2( movd ebx, mm4 ) \
690 AS2( movd esi, mm5 ) \
691 AS2( mov esp, ebp ) \
703 #ifdef OLD_GCC_OFFSET
709 AS2( mov eax, DWORD PTR [esi] )
710 AS2( mov ebx, DWORD PTR [esi + 4] )
759 AS2( mov esi, DWORD PTR [ebp + 16] )
761 AS2( mov esi, DWORD PTR [ebp + 12] )
764 AS2( mov DWORD PTR [esi], ebx )
765 AS2( mov DWORD PTR [esi + 4], eax )
773 #endif // defined(DO_DES_ASM)