2
Copyright (C) 2000-2007 MySQL AB
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; version 2 of the License.
8
This program is distributed in the hope that it will be useful,
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License
14
along with this program; see the file COPYING. If not, write to the
15
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
19
/* C++ part based on Wei Dai's des.cpp from CryptoPP */
20
/* x86 asm is original */
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;
44
/* permuted choice table (key) */
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
57
/* number left rotations of pc1 */
58
static const byte totrot[] = {
59
1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
62
/* permuted choice key (table) */
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
74
/* End of DES-defined tables */
76
/* bit 0 is left-most in byte */
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 /*length*/, CipherDir dir)
223
byte buffer[56+56+8];
224
byte *const pc1m = buffer; /* place to modify pc1 into */
225
byte *const pcr = pc1m + 56; /* place to rotate pc1 into */
226
byte *const ks = pcr + 56;
230
for (j = 0; j < 56; j++) { /* convert pc1 to bits of key */
231
l = pc1[j] - 1; /* integer bit location */
232
m = l & 07; /* find bit */
233
pc1m[j] = (key[l >> 3] & /* find which key byte l is in */
234
bytebit[m]) /* and which bit of that byte */
235
? 1 : 0; /* and store 1-bit result */
237
for (i = 0; i < 16; i++) { /* key chunk for each iteration */
238
memset(ks, 0, 8); /* Clear key schedule */
239
for (j = 0; j < 56; j++) /* rotate pc1 the right amount */
240
pcr[j] = pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l: l-28];
241
/* rotate left and right halves independently */
242
for (j = 0; j < 48; j++){ /* select bits individually */
243
/* check bit that goes to ks[j] */
244
if (pcr[pc2[j] - 1]){
245
/* mask it in if it's there */
247
ks[j/6] |= bytebit[l] >> 2;
250
/* Now convert to odd/even interleaved form for use in F */
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)
261
// reverse key schedule order
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, 4U);
275
work = (left ^ right) & 0xf0f0f0f0;
278
right = rotrFixed(right^work, 20U);
279
work = (left ^ right) & 0xffff0000;
282
right = rotrFixed(right^work, 18U);
283
work = (left ^ right) & 0x33333333;
286
right = rotrFixed(right^work, 6U);
287
work = (left ^ right) & 0x00ff00ff;
290
right = rotlFixed(right^work, 9U);
291
work = (left ^ right) & 0xaaaaaaaa;
292
left = rotlFixed(left^work, 1U);
296
static inline void FPERM(word32& left, word32& right)
300
right = rotrFixed(right, 1U);
301
work = (left ^ right) & 0xaaaaaaaa;
303
left = rotrFixed(left^work, 9U);
304
work = (left ^ right) & 0x00ff00ff;
306
left = rotlFixed(left^work, 6U);
307
work = (left ^ right) & 0x33333333;
309
left = rotlFixed(left^work, 18U);
310
work = (left ^ right) & 0xffff0000;
312
left = rotlFixed(left^work, 20U);
313
work = (left ^ right) & 0xf0f0f0f0;
315
left = rotrFixed(left^work, 4U);
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, 4U) ^ 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, 4U) ^ 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)
404
// ia32 optimized version
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)
469
/* Uses IPERM algorithm from above
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 ) }
510
/* Uses FPERM algorithm from above
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 ) \
553
/* DesRound implements this algorithm:
555
word32 work = rotrFixed(r, 4U) ^ key[0];
556
l ^= Spbox[6][(work) & 0x3f]
557
^ Spbox[4][(work >> 8) & 0x3f]
558
^ Spbox[2][(work >> 16) & 0x3f]
559
^ Spbox[0][(work >> 24) & 0x3f];
561
l ^= Spbox[7][(work) & 0x3f]
562
^ Spbox[5][(work >> 8) & 0x3f]
563
^ Spbox[3][(work >> 16) & 0x3f]
564
^ Spbox[1][(work >> 24) & 0x3f];
566
work = rotrFixed(l, 4U) ^ key[2];
567
r ^= Spbox[6][(work) & 0x3f]
568
^ Spbox[4][(work >> 8) & 0x3f]
569
^ Spbox[2][(work >> 16) & 0x3f]
570
^ Spbox[0][(work >> 24) & 0x3f];
572
r ^= Spbox[7][(work) & 0x3f]
573
^ Spbox[5][(work >> 8) & 0x3f]
574
^ Spbox[3][(work >> 16) & 0x3f]
575
^ Spbox[1][(work >> 24) & 0x3f];
581
edvances key for next round
583
uses ecx, esi, and edi
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] )
663
// ebp restored at end
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] )
686
// ebp restored at end
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
704
AS2( add edx, 60 ) // des1 = des1 key
706
AS2( add edx, 56 ) // des1 = des1 key
709
AS2( mov eax, DWORD PTR [esi] )
710
AS2( mov ebx, DWORD PTR [esi + 4] )
711
AS1( bswap eax ) // left
712
AS1( bswap ebx ) // right
725
// swap left and right
737
// swap left and right
754
// swap and write out
759
AS2( mov esi, DWORD PTR [ebp + 16] ) // outBlock
761
AS2( mov esi, DWORD PTR [ebp + 12] ) // outBlock
764
AS2( mov DWORD PTR [esi], ebx ) // right first
765
AS2( mov DWORD PTR [esi + 4], eax )
773
#endif // defined(DO_DES_ASM)