📄 des.cpp
字号:
des1_.RawProcessBlock(l, r);
des2_.RawProcessBlock(r, l);
des1_.RawProcessBlock(l, r);
FPERM(l,r);
Block::Put(xOr, out)(r)(l);
}
void DES_EDE3::SetKey(const byte* key, word32 sz, CipherDir dir)
{
des1_.SetKey(key+(dir==ENCRYPTION?0:2*8), sz, dir);
des2_.SetKey(key+8, sz, ReverseDir(dir));
des3_.SetKey(key+(dir==DECRYPTION?0:2*8), sz, dir);
}
#if !defined(DO_DES_ASM)
// Generic Version
void DES_EDE3::Process(byte* out, const byte* in, word32 sz)
{
if (mode_ == ECB)
ECB_Process(out, in, sz);
else if (mode_ == CBC)
if (dir_ == ENCRYPTION)
CBC_Encrypt(out, in, sz);
else
CBC_Decrypt(out, in, sz);
}
#else
// ia32 optimized version
void DES_EDE3::Process(byte* out, const byte* in, word32 sz)
{
word32 blocks = sz / DES_BLOCK_SIZE;
if (mode_ == CBC)
if (dir_ == ENCRYPTION)
while (blocks--) {
r_[0] ^= *(word32*)in;
r_[1] ^= *(word32*)(in + 4);
AsmProcess((byte*)r_, (byte*)r_, (void*)Spbox);
memcpy(out, r_, DES_BLOCK_SIZE);
in += DES_BLOCK_SIZE;
out += DES_BLOCK_SIZE;
}
else
while (blocks--) {
AsmProcess(in, out, (void*)Spbox);
*(word32*)out ^= r_[0];
*(word32*)(out + 4) ^= r_[1];
memcpy(r_, in, DES_BLOCK_SIZE);
out += DES_BLOCK_SIZE;
in += DES_BLOCK_SIZE;
}
else
while (blocks--) {
AsmProcess(in, out, (void*)Spbox);
out += DES_BLOCK_SIZE;
in += DES_BLOCK_SIZE;
}
}
#endif // DO_DES_ASM
void DES_EDE3::ProcessAndXorBlock(const byte* in, const byte* xOr,
byte* out) const
{
word32 l,r;
Block::Get(in)(l)(r);
IPERM(l,r);
des1_.RawProcessBlock(l, r);
des2_.RawProcessBlock(r, l);
des3_.RawProcessBlock(l, r);
FPERM(l,r);
Block::Put(xOr, out)(r)(l);
}
#if defined(DO_DES_ASM)
/* Uses IPERM algorithm from above
left is in eax
right is in ebx
uses ecx
*/
#define AsmIPERM() {\
AS2( rol ebx, 4 ) \
AS2( mov ecx, eax ) \
AS2( xor ecx, ebx ) \
AS2( and ecx, 0xf0f0f0f0 ) \
AS2( xor ebx, ecx ) \
AS2( xor eax, ecx ) \
AS2( ror ebx, 20 ) \
AS2( mov ecx, eax ) \
AS2( xor ecx, ebx ) \
AS2( and ecx, 0xffff0000 ) \
AS2( xor ebx, ecx ) \
AS2( xor eax, ecx ) \
AS2( ror ebx, 18 ) \
AS2( mov ecx, eax ) \
AS2( xor ecx, ebx ) \
AS2( and ecx, 0x33333333 ) \
AS2( xor ebx, ecx ) \
AS2( xor eax, ecx ) \
AS2( ror ebx, 6 ) \
AS2( mov ecx, eax ) \
AS2( xor ecx, ebx ) \
AS2( and ecx, 0x00ff00ff ) \
AS2( xor ebx, ecx ) \
AS2( xor eax, ecx ) \
AS2( rol ebx, 9 ) \
AS2( mov ecx, eax ) \
AS2( xor ecx, ebx ) \
AS2( and ecx, 0xaaaaaaaa ) \
AS2( xor eax, ecx ) \
AS2( rol eax, 1 ) \
AS2( xor ebx, ecx ) }
/* Uses FPERM algorithm from above
left is in eax
right is in ebx
uses ecx
*/
#define AsmFPERM() {\
AS2( ror ebx, 1 ) \
AS2( mov ecx, eax ) \
AS2( xor ecx, ebx ) \
AS2( and ecx, 0xaaaaaaaa ) \
AS2( xor eax, ecx ) \
AS2( xor ebx, ecx ) \
AS2( ror eax, 9 ) \
AS2( mov ecx, ebx ) \
AS2( xor ecx, eax ) \
AS2( and ecx, 0x00ff00ff ) \
AS2( xor eax, ecx ) \
AS2( xor ebx, ecx ) \
AS2( rol eax, 6 ) \
AS2( mov ecx, ebx ) \
AS2( xor ecx, eax ) \
AS2( and ecx, 0x33333333 ) \
AS2( xor eax, ecx ) \
AS2( xor ebx, ecx ) \
AS2( rol eax, 18 ) \
AS2( mov ecx, ebx ) \
AS2( xor ecx, eax ) \
AS2( and ecx, 0xffff0000 ) \
AS2( xor eax, ecx ) \
AS2( xor ebx, ecx ) \
AS2( rol eax, 20 ) \
AS2( mov ecx, ebx ) \
AS2( xor ecx, eax ) \
AS2( and ecx, 0xf0f0f0f0 ) \
AS2( xor eax, ecx ) \
AS2( xor ebx, ecx ) \
AS2( ror eax, 4 ) }
/* DesRound implements this algorithm:
word32 work = rotrFixed(r, 4U) ^ key[0];
l ^= Spbox[6][(work) & 0x3f]
^ Spbox[4][(work >> 8) & 0x3f]
^ Spbox[2][(work >> 16) & 0x3f]
^ Spbox[0][(work >> 24) & 0x3f];
work = r ^ key[1];
l ^= Spbox[7][(work) & 0x3f]
^ Spbox[5][(work >> 8) & 0x3f]
^ Spbox[3][(work >> 16) & 0x3f]
^ Spbox[1][(work >> 24) & 0x3f];
work = rotrFixed(l, 4U) ^ key[2];
r ^= Spbox[6][(work) & 0x3f]
^ Spbox[4][(work >> 8) & 0x3f]
^ Spbox[2][(work >> 16) & 0x3f]
^ Spbox[0][(work >> 24) & 0x3f];
work = l ^ key[3];
r ^= Spbox[7][(work) & 0x3f]
^ Spbox[5][(work >> 8) & 0x3f]
^ Spbox[3][(work >> 16) & 0x3f]
^ Spbox[1][(work >> 24) & 0x3f];
left is in aex
right is in ebx
key is in edx
edvances key for next round
uses ecx, esi, and edi
*/
#define DesRound() \
AS2( mov ecx, ebx )\
AS2( mov esi, DWORD PTR [edx] )\
AS2( ror ecx, 4 )\
AS2( xor ecx, esi )\
AS2( and ecx, 0x3f3f3f3f )\
AS2( movzx esi, cl )\
AS2( movzx edi, ch )\
AS2( xor eax, [ebp + esi*4 + 6*256] )\
AS2( shr ecx, 16 )\
AS2( xor eax, [ebp + edi*4 + 4*256] )\
AS2( movzx esi, cl )\
AS2( movzx edi, ch )\
AS2( xor eax, [ebp + esi*4 + 2*256] )\
AS2( mov esi, DWORD PTR [edx + 4] )\
AS2( xor eax, [ebp + edi*4] )\
AS2( mov ecx, ebx )\
AS2( xor ecx, esi )\
AS2( and ecx, 0x3f3f3f3f )\
AS2( movzx esi, cl )\
AS2( movzx edi, ch )\
AS2( xor eax, [ebp + esi*4 + 7*256] )\
AS2( shr ecx, 16 )\
AS2( xor eax, [ebp + edi*4 + 5*256] )\
AS2( movzx esi, cl )\
AS2( movzx edi, ch )\
AS2( xor eax, [ebp + esi*4 + 3*256] )\
AS2( mov esi, DWORD PTR [edx + 8] )\
AS2( xor eax, [ebp + edi*4 + 1*256] )\
AS2( mov ecx, eax )\
AS2( ror ecx, 4 )\
AS2( xor ecx, esi )\
AS2( and ecx, 0x3f3f3f3f )\
AS2( movzx esi, cl )\
AS2( movzx edi, ch )\
AS2( xor ebx, [ebp + esi*4 + 6*256] )\
AS2( shr ecx, 16 )\
AS2( xor ebx, [ebp + edi*4 + 4*256] )\
AS2( movzx esi, cl )\
AS2( movzx edi, ch )\
AS2( xor ebx, [ebp + esi*4 + 2*256] )\
AS2( mov esi, DWORD PTR [edx + 12] )\
AS2( xor ebx, [ebp + edi*4] )\
AS2( mov ecx, eax )\
AS2( xor ecx, esi )\
AS2( and ecx, 0x3f3f3f3f )\
AS2( movzx esi, cl )\
AS2( movzx edi, ch )\
AS2( xor ebx, [ebp + esi*4 + 7*256] )\
AS2( shr ecx, 16 )\
AS2( xor ebx, [ebp + edi*4 + 5*256] )\
AS2( movzx esi, cl )\
AS2( movzx edi, ch )\
AS2( xor ebx, [ebp + esi*4 + 3*256] )\
AS2( add edx, 16 )\
AS2( xor ebx, [ebp + edi*4 + 1*256] )
#ifdef _MSC_VER
__declspec(naked)
#endif
void DES_EDE3::AsmProcess(const byte* in, byte* out, void* box) const
{
#ifdef __GNUC__
#define AS1(x) asm(#x);
#define AS2(x, y) asm(#x ", " #y);
asm(".intel_syntax noprefix");
#define PROLOG() \
AS2( movd mm3, edi ) \
AS2( movd mm4, ebx ) \
AS2( movd mm5, esi ) \
AS2( movd mm6, ebp ) \
AS2( mov edx, DWORD PTR [ebp + 8] ) \
AS2( mov esi, DWORD PTR [ebp + 12] ) \
AS2( mov ebp, DWORD PTR [ebp + 20] )
// ebp restored at end
#define EPILOG() \
AS2( movd edi, mm3 ) \
AS2( movd ebx, mm4 ) \
AS2( movd esi, mm5 ) \
AS1( emms ) \
asm(".att_syntax");
#else
#define AS1(x) __asm x
#define AS2(x, y) __asm x, y
#define PROLOG() \
AS1( push ebp ) \
AS2( mov ebp, esp ) \
AS2( movd mm3, edi ) \
AS2( movd mm4, ebx ) \
AS2( movd mm5, esi ) \
AS2( movd mm6, ebp ) \
AS2( mov esi, DWORD PTR [ebp + 8] ) \
AS2( mov edx, ecx ) \
AS2( mov ebp, DWORD PTR [ebp + 16] )
// ebp restored at end
#define EPILOG() \
AS2( movd edi, mm3 ) \
AS2( movd ebx, mm4 ) \
AS2( movd esi, mm5 ) \
AS2( mov esp, ebp ) \
AS1( pop ebp ) \
AS1( emms ) \
AS1( ret 12 )
#endif
PROLOG()
AS2( movd mm2, edx )
#ifdef OLD_GCC_OFFSET
AS2( add edx, 60 ) // des1 = des1 key
#else
AS2( add edx, 56 ) // des1 = des1 key
#endif
AS2( mov eax, DWORD PTR [esi] )
AS2( mov ebx, DWORD PTR [esi + 4] )
AS1( bswap eax ) // left
AS1( bswap ebx ) // right
AsmIPERM()
DesRound() // 1
DesRound() // 2
DesRound() // 3
DesRound() // 4
DesRound() // 5
DesRound() // 6
DesRound() // 7
DesRound() // 8
// swap left and right
AS2( xchg eax, ebx )
DesRound() // 1
DesRound() // 2
DesRound() // 3
DesRound() // 4
DesRound() // 5
DesRound() // 6
DesRound() // 7
DesRound() // 8
// swap left and right
AS2( xchg eax, ebx )
DesRound() // 1
DesRound() // 2
DesRound() // 3
DesRound() // 4
DesRound() // 5
DesRound() // 6
DesRound() // 7
DesRound() // 8
AsmFPERM()
//end
AS2( movd ebp, mm6 )
// swap and write out
AS1( bswap ebx )
AS1( bswap eax )
#ifdef __GNUC__
AS2( mov esi, DWORD PTR [ebp + 16] ) // outBlock
#else
AS2( mov esi, DWORD PTR [ebp + 12] ) // outBlock
#endif
AS2( mov DWORD PTR [esi], ebx ) // right first
AS2( mov DWORD PTR [esi + 4], eax )
EPILOG()
}
#endif // defined(DO_DES_ASM)
} // namespace
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -