📄 desborl.cas
字号:
/* Borland C++ inline assembler version of des() function */#pragma inline#include "des.h"/* Primitive function F. Input is r, output is XORed into l. * Subkeys are taken from the array pointed to by es:si. * eax and ebx are scratch, ebx is assumed to be initialized to 0. * * There's an important difference between this version and the portable C * version: here, each subkey is LEFT JUSTIFIED within a byte, i.e., left * shifted 2 bits. This lets us avoid the two left shifts we'd otherwise have * to do here to get double word indexes for addressing each S-box (an array * of 4-byte longs). Several other places in the code take this into account: * * the initial permutation left-shifts r and l by two additional bits * (for a total of three); * * the values in Spboxa[] generated by gensp.c are also shifted left by * two additional bits (for a total of three); * * deskey() left shifts each key schedule byte left by two places. * * Since this code is executed 16 times in every DES encrypt or decrypt * operation, it is very time-critical. It has been very heavily * optimized for the 486. 32-bit operations are done whenever possible, * and indexed addressing is used instead of incremented pointers. */#define F(l,r,key)\ /* eax = ((r >>> 4) ^ key[0]) & 0xfcfcfcfc */\ mov eax,r;\ ror eax,4;\ xor eax,key[es:si];\ and eax,0fcfcfcfch;\\ /* eax now contains four S-box offsets all ready for use */\ mov bl,al;\ xor l,dword ptr Spboxa[bx+6*256] ; /* l ^= Spboxa[6][al] */\ mov bl,ah;\ ror eax,16;\ xor l,dword ptr Spboxa[bx+4*256] ; /* l ^= Spboxa[4][al] */\ mov bl,al;\ xor l,dword ptr Spboxa[bx+2*256] ; /* l ^= Spboxa[2][al] */\ mov bl,ah;\ xor l,dword ptr Spboxa[bx+0*256] ; /* l ^= Spboxa[0][al] */\\ /* eax = (r ^ key[1]) & 0xfcfcfcfc */\ mov eax,key+4[es:si];\ xor eax,r;\ and eax,0fcfcfcfch;\\ /* eax now contains four S-box offsets all ready for use */\ mov bl,al;\ xor l,dword ptr Spboxa[bx+7*256] ; /* l ^= Spboxa[7][al] */\ mov bl,ah;\ ror eax,16;\ xor l,dword ptr Spboxa[bx+5*256] ; /* l ^= Spboxa[5][al] */\ mov bl,al;\ xor l,dword ptr Spboxa[bx+3*256] ; /* l ^= Spboxa[3][al] */\ mov bl,ah;\ xor l,dword ptr Spboxa[bx+1*256] ; /* l ^= Spboxa[1][al] */int Asmversion = 1; /* Let deskey() know we need shifted keys *//* Encrypt or decrypt a block of data in ECB mode with the key schedule * provided (encryption/decryption is selected by the key schedule) * * Register assignments: * eax - working scratch * ebx - offset into Spboxa table (low byte only, upper is 0) * ecx - left data half * edx - right data half * es:si - working memory pointer (user's data buffer, key schedule) */ voiddes(ks,block)unsigned long ks[16][2]; /* Key schedule */unsigned char block[8]; /* Data block */{ extern unsigned long Spboxa[8][64]; asm { /* Fetch 8 bytes from user's buffer in "block" and place in ecx and edx, * in big-endian order. Uses es, si. * There's a very nice BSWAP instruction that executes in only * 1 cycle, but it is only available on the 486. :-( */ les si,block; /* es:si = block */ mov ecx,[es:si]; /* ecx = ((long *)block)[0] */ xchg cl,ch; /* bswap ecx */ rol ecx,16; xchg cl,ch; mov edx,4[es:si]; /* edx = ((long *)block)[1] */ xchg dl,dh; /* bswap edx */ rol edx,16; xchg dl,dh; /* Hoey's clever initial permutation algorithm, translated to assembler * (see Schneier p 478) * * The convention here is *different* from the C version. The permuted * values of "left" and "right" are rotated left by two additional * bits so we can avoid the two shifts that would otherwise be * required in each round to convert a S-box input to a memory offset * for Spboxa[]. */ /* work = ((left >> 4) ^ right) & 0x0f0f0f0f */ mov eax,ecx; shr eax,4; xor eax,edx; and eax,0f0f0f0fh; xor edx,eax; /* right ^= work */ /* left ^= work << 4 */ shl eax,4; xor ecx,eax; /* work = ((left >> 16) ^ right) & 0xffff */ mov eax,ecx; shr eax,16; xor eax,edx; and eax,0ffffh; xor edx,eax; /* right ^= work */ /* left ^= work << 16 */ shl eax,16; xor ecx,eax; /* work = ((right >> 2) ^ left) & 0x33333333 */ mov eax,edx; shr eax,2; xor eax,ecx; and eax,033333333h; /* left ^= work */ xor ecx,eax; shl eax,2; xor edx,eax; /* right ^= (work << 2) */ /* work = ((right >> 8) ^ left) & 0xff00ff */ mov eax,edx; shr eax,8; xor eax,ecx; and eax,0ff00ffh; xor ecx,eax; /* left ^= work */ /* right ^= (work << 8) */ shl eax,8; xor edx,eax; rol edx,1; /* right <<<= 1 */ /* work = (left ^ right) & 0xaaaaaaaa */ mov eax,ecx; xor eax,edx; and eax,0aaaaaaaah; xor ecx,eax; /* left ^= work */ xor edx,eax; /* right ^= work */ rol ecx,3; /* left <<<= 3 */ rol edx,2; /* right <<<= 2 */ /* Set up for the rounds */ les si,ss:ks; /* es:si = key schedule */ mov ebx,0; /* Upper 3 bytes must be zero */ /* Do the rounds */ F(ecx,edx,0); F(edx,ecx,8); F(ecx,edx,16); F(edx,ecx,24); F(ecx,edx,32); F(edx,ecx,40); F(ecx,edx,48); F(edx,ecx,56); F(ecx,edx,64); F(edx,ecx,72); F(ecx,edx,80); F(edx,ecx,88); F(ecx,edx,96); F(edx,ecx,104); F(ecx,edx,112); F(edx,ecx,120); /* Inverse permutation */ ror ecx,2; /* left >>>= 2 */ ror edx,3; /* right >>>= 3 */ /* work = (left ^ right) & 0xaaaaaaaa */ mov eax,ecx; xor eax,edx; and eax,0aaaaaaaah; xor ecx,eax; /* left ^= work */ xor edx,eax; /* right ^= work */ ror ecx,1; /* left >>>= 1 */ /* work = (left >> 8) ^ right) & 0xff00ff */ mov eax,ecx; shr eax,8; xor eax,edx; and eax,0ff00ffh; xor edx,eax; /* right ^= work */ /* left ^= work << 8 */ shl eax,8; xor ecx,eax; /* work = ((left >> 2) ^ right) & 0x33333333 */ mov eax,ecx; shr eax,2; xor eax,edx; and eax,33333333h; xor edx,eax; /* right ^= work */ /* left ^= work << 2 */ shl eax,2; xor ecx,eax; /* work = ((right >> 16) ^ left) & 0xffff */ mov eax,edx; shr eax,16; xor eax,ecx; and eax,0ffffh; xor ecx,eax; /* left ^= work */ /* right ^= work << 16 */ shl eax,16; xor edx,eax; /* work = ((right >> 4) ^ left) & 0x0f0f0f0f */ mov eax,edx; shr eax,4; xor eax,ecx; and eax,0f0f0f0fh; xor ecx,eax; /* left ^= work */ /* right ^= work << 4 */ shl eax,4; xor edx,eax; /* Write ecx and edx into user's buffer "block" in big-endian order * after final swap * Uses es, si */ les si,block; xchg dl,dh; /* bswap edx */ rol edx,16; xchg dl,dh; mov [es:si],edx; xchg cl,ch; /* bswap ecx */ rol ecx,16; xchg cl,ch; mov 4[es:si],ecx; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -