Libgcrypt解析
DES
code:des.c
/*
* Macro to swap bits across two words.
*/
#define DO_PERMUTATION(a, temp, b, offset, mask) \ temp = ((a>>offset) ^ b) & mask; \
b ^= temp; \
a ^= temp<<offset;
// ^ ビットの反転
/*
* This performs the 'initial permutation' of the data to be encrypted
* or decrypted. Additionally the resulting two words are rotated one bit
* to the left.
*/
#define INITIAL_PERMUTATION(left, temp, right) \ DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f) \
DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \
DO_PERMUTATION(right, temp, left, 2, 0x33333333) \
DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \
right = (right << 1) | (right >> 31); \ //
temp = (left ^ right) & 0xaaaaaaaa; \
right ^= temp; \
left ^= temp; \
left = (left << 1) | (left >> 31);
// temp
// = ((FFFF FFFF << 4) ^ FFFF FFFF) & 0x0f0f0f0f
// = (FFFF FFF0 ^ FFFF FFFF) & 0f0f 0f0f
// = (0000 000F) & 0f0f 0f0f
// = 0000 000F
// b = FFFF FFFF ^ 0000 000F = FFFF FFF0
// a = 0000 000F << 4 = 0000 00F0
//
// temp
// = ((0000 000F << 16) ^ FFFF FFF0) & 0x0000ffff
// = (000F 0000 ^ FFFF FFF0) & 0000 ffff
// = (FFF0 FFF0) & 0000 ffff
// = 0000 FFF0
// b = FFFF FFF0 ^ 0000 FFF0 = FFFF 000F
// a = 0000 F0F0 << 16 = F0F0 0000
// temp
// = ((F0F0 0000 << 2) ^ FFFF 000F) & 0x33333333(01110111 01110111 01110111 01110111)
// = (F000 0000 ^ FFFF 000F) & 3333 3333
// = (0FFF 000F) & 3333 3333
// = 0000 FFF0
// b = FFFF FFF0 ^ 0000 FFF0 = FFFF 000F
// a = 0000 F0F0 << 16 = F0F0 0000
/*
* The 'inverse initial permutation'.
*/
#define FINAL_PERMUTATION(left, temp, right) \ left = (left << 31) | (left >> 1); \
temp = (left ^ right) & 0xaaaaaaaa; \
left ^= temp; \
right ^= temp; \
right = (right << 31) | (right >> 1); \
DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \
DO_PERMUTATION(right, temp, left, 2, 0x33333333) \
DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \
DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f)
/*
* Macros to convert 8 bytes from/to 32bit words.
*/
#define READ_64BIT_DATA(data, left, right) \ left = (data0 << 24) | (data1 << 16) | (data2 << 8) | data3; \ right = (data4 << 24) | (data5 << 16) | (data6 << 8) | data7; #define WRITE_64BIT_DATA(data, left, right) \ data0 = (left >> 24) &0xff; data1 = (left >> 16) &0xff; \ data2 = (left >> 8) &0xff; data3 = left &0xff; \ data4 = (right >> 24) &0xff; data5 = (right >> 16) &0xff; \ data6 = (right >> 8) &0xff; data7 = right &0xff; /*
* Handy macros for encryption and decryption of data
*/
#define des_ecb_encrypt(ctx, from, to) des_ecb_crypt(ctx, from, to, 0) #define des_ecb_decrypt(ctx, from, to) des_ecb_crypt(ctx, from, to, 1) #define tripledes_ecb_encrypt(ctx, from, to) tripledes_ecb_crypt(ctx,from,to,0) #define tripledes_ecb_decrypt(ctx, from, to) tripledes_ecb_crypt(ctx,from,to,1) /*
* Electronic Codebook Mode DES encryption/decryption of data according
* to 'mode'.
*/
static int
des_ecb_crypt (struct _des_ctx *ctx, const byte * from, byte * to, int mode)
{
u32 left, right, work;
u32 *keys;
keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys;
READ_64BIT_DATA (from, left, right)
INITIAL_PERMUTATION (left, work, right)
DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
FINAL_PERMUTATION (right, work, left)
WRITE_64BIT_DATA (to, right, left)
return 0;
}