des.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 684 行 · 第 1/2 页

C
684
字号
/* * The PC-1 Permutation * If we number the bits of the 8 bytes of key input like this (in octal): *     00 01 02 03 04 05 06 07  *     10 11 12 13 14 15 16 17  *     20 21 22 23 24 25 26 27  *     30 31 32 33 34 35 36 37  *     40 41 42 43 44 45 46 47  *     50 51 52 53 54 55 56 57  *     60 61 62 63 64 65 66 67  *     70 71 72 73 74 75 76 77  * then after the PC-1 permutation,  * C0 is *     70 60 50 40 30 20 10 00  *     71 61 51 41 31 21 11 01  *     72 62 52 42 32 22 12 02  *     73 63 53 43  * D0 is *     76 66 56 46 36 26 16 06  *     75 65 55 45 35 25 15 05  *     74 64 54 44 34 24 14 04  *                 33 23 13 03  * and these parity bits have been discarded: *     77 67 57 47 37 27 17 07  *  * We achieve this by flipping the input matrix about the diagonal from 70-07, * getting left =  *     77 67 57 47 37 27 17 07 	(these are the parity bits) *     76 66 56 46 36 26 16 06  *     75 65 55 45 35 25 15 05  *     74 64 54 44 34 24 14 04  * right =  *     73 63 53 43 33 23 13 03  *     72 62 52 42 32 22 12 02  *     71 61 51 41 31 21 11 01  *     70 60 50 40 30 20 10 00  * then byte swap right, ala htonl() on a little endian machine. * right =  *     70 60 50 40 30 20 10 00  *     71 67 57 47 37 27 11 07  *     72 62 52 42 32 22 12 02  *     73 63 53 43 33 23 13 03  * then *     c0 = right >> 4; *     d0 = ((left & 0x00ffffff) << 4) | (right & 0xf);*/#define FLIP_RIGHT_DIAGONAL(word, temp) \    temp  = (word ^ (word >> 18)) & 0x00003333; \    word ^=  temp | (temp << 18); \    temp  = (word ^ (word >> 9)) & 0x00550055; \    word ^=  temp | (temp << 9);#define BYTESWAP(word, temp) \    word = (word >> 16) | (word << 16); \    temp = 0x00ff00ff; \    word = ((word & temp) << 8) | ((word >> 8) & temp); #define PC1(left, right, c0, d0, temp) \    right ^= temp = ((left >> 4) ^ right) & 0x0f0f0f0f; \    left  ^= temp << 4; \    FLIP_RIGHT_DIAGONAL(left, temp); \    FLIP_RIGHT_DIAGONAL(right, temp); \    BYTESWAP(right, temp); \    c0 = right >> 4; \    d0 = ((left & 0x00ffffff) << 4) | (right & 0xf); #define LEFT_SHIFT_1( reg ) (((reg << 1) | (reg >> 27)) & 0x0FFFFFFF)#define LEFT_SHIFT_2( reg ) (((reg << 2) | (reg >> 26)) & 0x0FFFFFFF)/* *   setup key schedules from key */void DES_MakeSchedule( HALF * ks, BYTE * key,   DESDirection direction){    register HALF left, right;    register HALF c0, d0;    register HALF temp;    int           delta;    unsigned int  ls;#if defined(_X86_)    left  = HALFPTR(key)[0];     right = HALFPTR(key)[1];     BYTESWAP(left, temp);    BYTESWAP(right, temp);#else    if (((ptrdiff_t)key & 0x03) == 0) {	left  = HALFPTR(key)[0]; 	right = HALFPTR(key)[1]; #if defined(IS_LITTLE_ENDIAN)	BYTESWAP(left, temp);	BYTESWAP(right, temp);#endif    } else {	left    = ((HALF)key[0] << 24) | ((HALF)key[1] << 16) | 		  ((HALF)key[2] << 8)  | key[3];	right   = ((HALF)key[4] << 24) | ((HALF)key[5] << 16) | 		  ((HALF)key[6] << 8)  | key[7];    }#endif    PC1(left, right, c0, d0, temp);    if (direction == DES_ENCRYPT) {	delta = 2 * (int)sizeof(HALF);    } else {	ks += 30;	delta = (-2) * (int)sizeof(HALF);    }    for (ls = 0x8103; ls; ls >>= 1) {	if ( ls & 1 ) {	    c0 = LEFT_SHIFT_1( c0 );	    d0 = LEFT_SHIFT_1( d0 );	} else {	    c0 = LEFT_SHIFT_2( c0 );	    d0 = LEFT_SHIFT_2( d0 );	}#ifdef USE_INDEXING#define PC2LOOKUP(b,c) PC2[b][c]	left   = PC2LOOKUP(0, ((c0 >> 22) & 0x3F) );	left  |= PC2LOOKUP(1, ((c0 >> 13) & 0x3F) );	left  |= PC2LOOKUP(2, ((c0 >>  4) & 0x38) | (c0 & 0x7) );	left  |= PC2LOOKUP(3, ((c0>>18)&0xC) | ((c0>>11)&0x3) | (c0&0x30));	right  = PC2LOOKUP(4, ((d0 >> 22) & 0x3F) );	right |= PC2LOOKUP(5, ((d0 >> 15) & 0x30) | ((d0 >> 14) & 0xf) );	right |= PC2LOOKUP(6, ((d0 >>  7) & 0x3F) );	right |= PC2LOOKUP(7, ((d0 >>  1) & 0x3C) | (d0 & 0x3));#else#define PC2LOOKUP(b,c) *(HALF *)((BYTE *)&PC2[b][0]+(c))	left   = PC2LOOKUP(0, ((c0 >> 20) & 0xFC) );	left  |= PC2LOOKUP(1, ((c0 >> 11) & 0xFC) );	left  |= PC2LOOKUP(2, ((c0 >>  2) & 0xE0) | ((c0 <<  2) & 0x1C) );	left  |= PC2LOOKUP(3, ((c0>>16)&0x30)|((c0>>9)&0xC)|((c0<<2)&0xC0));	right  = PC2LOOKUP(4, ((d0 >> 20) & 0xFC) );	right |= PC2LOOKUP(5, ((d0 >> 13) & 0xC0) | ((d0 >> 12) & 0x3C) );	right |= PC2LOOKUP(6, ((d0 >>  5) & 0xFC) );	right |= PC2LOOKUP(7, ((d0 <<  1) & 0xF0) | ((d0 << 2) & 0x0C));#endif	/* left  contains key bits for S1 S3 S2 S4 */	/* right contains key bits for S6 S8 S5 S7 */	temp = (left  << 16)        /* S2 S4 XX XX */	     | (right >> 16);       /* XX XX S6 S8 */	ks[0] = temp;	temp = (left  & 0xffff0000) /* S1 S3 XX XX */	     | (right & 0x0000ffff);/* XX XX S5 S7 */	ks[1] = temp;	ks = (HALF*)((BYTE *)ks + delta);    }}/* * The DES Initial Permutation * if we number the bits of the 8 bytes of input like this (in octal): *     00 01 02 03 04 05 06 07  *     10 11 12 13 14 15 16 17  *     20 21 22 23 24 25 26 27  *     30 31 32 33 34 35 36 37  *     40 41 42 43 44 45 46 47  *     50 51 52 53 54 55 56 57  *     60 61 62 63 64 65 66 67  *     70 71 72 73 74 75 76 77  * then after the initial permutation, they will be in this order.  *     71 61 51 41 31 21 11 01  *     73 63 53 43 33 23 13 03  *     75 65 55 45 35 25 15 05  *     77 67 57 47 37 27 17 07  *     70 60 50 40 30 20 10 00  *     72 62 52 42 32 22 12 02  *     74 64 54 44 34 24 14 04  *     76 66 56 46 36 26 16 06  * * One way to do this is in two steps: * 1. Flip this matrix about the diagonal from 70-07 as done for PC1. * 2. Rearrange the bytes (rows in the matrix above) with the following code. * * #define swapHiLo(word, temp) \ *   temp  = (word ^ (word >> 24)) & 0x000000ff; \ *   word ^=  temp | (temp << 24);  * *   right ^= temp = ((left << 8) ^ right) & 0xff00ff00;  *   left  ^= temp >> 8;  *   swapHiLo(left, temp); *   swapHiLo(right,temp); * * However, the two steps can be combined, so that the rows are rearranged * while the matrix is being flipped, reducing the number of bit exchange * operations from 8 ot 5.   * * Initial Permutation */#define IP(left, right, temp) \    right ^= temp = ((left >> 4) ^  right) & 0x0f0f0f0f; \    left  ^= temp << 4; \    right ^= temp = ((left >> 16) ^ right) & 0x0000ffff; \    left  ^= temp << 16; \    right ^= temp = ((left << 2) ^ right) & 0xcccccccc; \    left  ^= temp >> 2; \    right ^= temp = ((left << 8) ^ right) & 0xff00ff00; \    left  ^= temp >> 8; \    right ^= temp = ((left >> 1) ^ right) & 0x55555555; \    left  ^= temp << 1; /* The Final (Inverse Initial) permutation is done by reversing the ** steps of the Initital Permutation */#define FP(left, right, temp) \    right ^= temp = ((left >> 1) ^ right) & 0x55555555; \    left  ^= temp << 1; \    right ^= temp = ((left << 8) ^ right) & 0xff00ff00; \    left  ^= temp >> 8; \    right ^= temp = ((left << 2) ^ right) & 0xcccccccc; \    left  ^= temp >> 2; \    right ^= temp = ((left >> 16) ^ right) & 0x0000ffff; \    left  ^= temp << 16; \    right ^= temp = ((left >> 4) ^  right) & 0x0f0f0f0f; \    left  ^= temp << 4; void DES_Do1Block(HALF * ks, BYTE * inbuf, BYTE * outbuf){    register HALF left, right;    register HALF temp;#if defined(_X86_)    left  = HALFPTR(inbuf)[0];     right = HALFPTR(inbuf)[1];     BYTESWAP(left, temp);    BYTESWAP(right, temp);#else    if (((ptrdiff_t)inbuf & 0x03) == 0) {	left  = HALFPTR(inbuf)[0]; 	right = HALFPTR(inbuf)[1]; #if defined(IS_LITTLE_ENDIAN)	BYTESWAP(left, temp);	BYTESWAP(right, temp);#endif    } else {	left    = ((HALF)inbuf[0] << 24) | ((HALF)inbuf[1] << 16) | 		  ((HALF)inbuf[2] << 8)  | inbuf[3];	right   = ((HALF)inbuf[4] << 24) | ((HALF)inbuf[5] << 16) | 		  ((HALF)inbuf[6] << 8)  | inbuf[7];    }#endif    IP(left, right, temp);    /* shift the values left circularly 3 bits. */    left  = (left  << 3) | (left  >> 29);    right = (right << 3) | (right >> 29);#ifdef USE_INDEXING#define KSLOOKUP(s,b) SP[s][((temp >> (b+2)) & 0x3f)]#else#define KSLOOKUP(s,b) *(HALF*)((BYTE*)&SP[s][0]+((temp >> b) & 0xFC))#endif#define ROUND(out, in, r) \    temp  = in ^ ks[2*r]; \    out ^= KSLOOKUP( 1,  24 ); \    out ^= KSLOOKUP( 3,  16 ); \    out ^= KSLOOKUP( 5,   8 ); \    out ^= KSLOOKUP( 7,   0 ); \    temp  = ((in >> 4) | (in << 28)) ^ ks[2*r+1]; \    out ^= KSLOOKUP( 0,  24 ); \    out ^= KSLOOKUP( 2,  16 ); \    out ^= KSLOOKUP( 4,   8 ); \    out ^= KSLOOKUP( 6,   0 );     /* Do the 16 Feistel rounds */    ROUND(left, right, 0)    ROUND(right, left, 1)    ROUND(left, right, 2)    ROUND(right, left, 3)    ROUND(left, right, 4)    ROUND(right, left, 5)    ROUND(left, right, 6)    ROUND(right, left, 7)    ROUND(left, right, 8)    ROUND(right, left, 9)    ROUND(left, right, 10)    ROUND(right, left, 11)    ROUND(left, right, 12)    ROUND(right, left, 13)    ROUND(left, right, 14)    ROUND(right, left, 15)    /* now shift circularly right 3 bits to undo the shifting done     ** above.  switch left and right here.     */    temp  = (left >> 3) | (left << 29);     left  = (right >> 3) | (right << 29);     right = temp;    FP(left, right, temp);#if defined(_X86_)    BYTESWAP(left, temp);    BYTESWAP(right, temp);    HALFPTR(outbuf)[0]  = left;     HALFPTR(outbuf)[1]  = right; #else    if (((ptrdiff_t)inbuf & 0x03) == 0) {#if defined(IS_LITTLE_ENDIAN)	BYTESWAP(left, temp);	BYTESWAP(right, temp);#endif	HALFPTR(outbuf)[0]  = left; 	HALFPTR(outbuf)[1]  = right;     } else {	outbuf[0] = (BYTE)(left >> 24);	outbuf[1] = (BYTE)(left >> 16);	outbuf[2] = (BYTE)(left >>  8);	outbuf[3] = (BYTE)(left      );	outbuf[4] = (BYTE)(right >> 24);	outbuf[5] = (BYTE)(right >> 16);	outbuf[6] = (BYTE)(right >>  8);	outbuf[7] = (BYTE)(right      );    }#endif}/* Ackowledgements:** Two ideas used in this implementation were shown to me by Dennis Ferguson ** in 1990.  He credits them to Richard Outerbridge and Dan Hoey.  They were:** 1. The method of computing the Initial and Final permutations.** 2. Circularly rotating the SP tables and the initial values of left and **	right to reduce the number of shifts required during the 16 rounds.*/

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?