⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgpdes3.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * pgpDES3.c - TripleDES EDE Encryptor
 *
 * pgpDES3.c 95/09/11 23:29:03 EDT by Richard Outerbridge
 *
 * $Id: pgpDES3.c,v 1.15 1997/10/14 01:48:17 heller Exp $
 */
 
  
#include "pgpSDKBuildFlags.h"

#ifndef PGP_DES3
#error you must define PGP_DES3 one way or the other
#endif

#if PGP_DES3	/* [ */


#include <string.h>
#include "pgpConfig.h"

#include "pgpSymmetricCipherPriv.h"
#include "pgpDES3.h"
#include "pgpMem.h"

/* The size of a scheduled DES key */
#define DES_KEYWORDS 32
#define DES_KEYBYTES (sizeof(PGPUInt32)*DES_KEYWORDS)
#define DES3_KEYWORDS (3*DES_KEYWORDS)
#define DES3_KEYBYTES (sizeof(PGPUInt32)*DES3_KEYWORDS)

#define DES3_USERKEYBYTES 24

/*
 * Flags in priv array to record whether key schedule is in encrypt
 * or decrypt mode
 */
#define DES3_MODE_OFFSET		(DES3_KEYBYTES + DES3_USERKEYBYTES)
#define DES3_UNDEFINED_MODE		0x00
#define DES3_ENCRYPTION_MODE	0x11
#define DES3_DECRYPTION_MODE	0x22


static PGPUInt32 const bigbyte[24] = {
	0x800000L,	0x400000L,	0x200000L, 	0x100000L,
	0x80000L,	0x40000L,	0x20000L,	0x10000L,
	0x8000L,	0x4000L,	0x2000L,	0x1000L,
	0x800L,		0x400L,		0x200L,		0x100L,
	0x80L,		0x40L,		0x20L,		0x10L,
	0x8L,		0x4L,		0x2L,		0x1L	};

/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */

static PGPByte const pc1[56] = {
	56, 48, 40, 32, 24, 16,  8,	 0, 57, 49, 41, 33, 25, 17,
	 9,  1, 58, 50, 42, 34, 26,	18, 10,  2, 59, 51, 43, 35,
	62, 54, 46, 38, 30, 22, 14,	 6, 61, 53, 45, 37, 29, 21,
	13,  5, 60, 52, 44, 36, 28,	20, 12,  4, 27, 19, 11,  3 };

static PGPByte const totrot[16] = {
	 1,  2,  4,  6,  8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 };

static PGPByte const pc2[48] = {
	13, 16, 10, 23,  0,  4,	 2, 27, 14,  5, 20,  9,
	22, 18, 11,  3, 25,  7,	15,  6, 26, 19, 12,  1,
	40, 51, 30, 36, 46, 54,	29, 39, 50, 44, 32, 47,
	43, 48, 38, 55, 33, 52,	45, 41, 49, 35, 28, 31 };

/*
 * This is a less-that-brilliant key scheduling routine.
 * It could stand optimization some time.
 *
 * cookey "cooks" the key into the desired form, from the basic one that
 * has the keys for S-boxes 1 through 8 in adjacent words of the
 * "raw" array.  I.e. the bits start out like this:
 * xxxxxxxx111111222222333333444444
 * xxxxxxxx555555666666777777888888
 * We actually want the keys to look like this:
 * 111111xx333333xx555555xx777777xx
 * 222222xx444444xx666666xx888888xx
 * Where the "xx" patterns are set to 01020300 for use by the s-box
 * lookup code in the main encrypt loop.
 */
static void
cookey (PGPUInt32 *raw, PGPUInt32 *cooked)
{
	int i;

	for (i = 0; i < 16; i++, raw += 2, cooked += 2) {
		cooked[0]  = (raw[0] & 0x00fc0000L) << 8;
		cooked[0] |= (raw[0] & 0x00000fc0L) << 12;
		cooked[0] |= (raw[1] & 0x00fc0000L) >> 8;
		cooked[0] |= (raw[1] & 0x00000fc0L) >> 4;
		cooked[0] |= 0x01020300;
		cooked[1]  = (raw[0] & 0x0003f000L) << 14;
		cooked[1] |= (raw[0] & 0x0000003fL) << 18;
		cooked[1] |= (raw[1] & 0x0003f000L) >> 2;
		cooked[1] |= (raw[1] & 0x0000003fL) << 2;
		cooked[1] |= 0x01020300;
	}
	return;
}
	
static void
deskey (PGPByte const *key, int decryptf, PGPUInt32 *outbuf)
{
	int i, j, l, m, n;
	PGPByte pc1m[56], pcr[56];
	PGPUInt32 kn[32];
	
	for (j = 0; j < 56; j++) {
		l = pc1[j];
		m = l & 07;
		pc1m[j] = ( key[l >> 3] >> (~l & 7) ) & 1;
	}
	for (i = 0; i < 16; i++ ) {
		m = (decryptf ? 15-i : i) << 1;
		n = m + 1;
		kn[m] = kn[n] = 0L;
		for (j = 0; j < 28; j++) {
			l = j + totrot[i];
			if (l >= 28)
				l -= 28;
			pcr[j] = pc1m[l];
		}
		for (j = 28; j < 56; j++) {
			l = j + totrot[i];
			if (l >= 56)
				l -= 28;
			pcr[j] = pc1m[l];
		}
		for (j = 0; j < 24; j++) {
			if (pcr[pc2[j]])
				kn[m] |= bigbyte[j];
			if (pcr[pc2[j+24]])
				kn[n] |= bigbyte[j];
		}
	}
	cookey(kn, outbuf);
	return;
}

/* S-boxes 1, 3, 5, 7, plus P permutation, rotated */
static PGPUInt32 const SP0[512] = {
	0x00404100, 0x00000000, 0x00004000, 0x00404101,
	0x00404001, 0x00004101, 0x00000001, 0x00004000,
	0x00000100, 0x00404100, 0x00404101, 0x00000100,
	0x00400101, 0x00404001, 0x00400000, 0x00000001,
	0x00000101, 0x00400100, 0x00400100, 0x00004100,
	0x00004100, 0x00404000, 0x00404000, 0x00400101,
	0x00004001, 0x00400001, 0x00400001, 0x00004001,
	0x00000000, 0x00000101, 0x00004101, 0x00400000,
	0x00004000, 0x00404101, 0x00000001, 0x00404000,
	0x00404100, 0x00400000, 0x00400000, 0x00000100,
	0x00404001, 0x00004000, 0x00004100, 0x00400001,
	0x00000100, 0x00000001, 0x00400101, 0x00004101,
	0x00404101, 0x00004001, 0x00404000, 0x00400101,
	0x00400001, 0x00000101, 0x00004101, 0x00404100,
	0x00000101, 0x00400100, 0x00400100, 0x00000000,
	0x00004001, 0x00004100, 0x00000000, 0x00404001,

	0x00000082, 0x02008080, 0x00000000, 0x02008002,
	0x02000080, 0x00000000, 0x00008082, 0x02000080,
	0x00008002, 0x02000002, 0x02000002, 0x00008000,
	0x02008082, 0x00008002, 0x02008000, 0x00000082,
	0x02000000, 0x00000002, 0x02008080, 0x00000080,
	0x00008080, 0x02008000, 0x02008002, 0x00008082,
	0x02000082, 0x00008080, 0x00008000, 0x02000082,
	0x00000002, 0x02008082, 0x00000080, 0x02000000,
	0x02008080, 0x02000000, 0x00008002, 0x00000082,
	0x00008000, 0x02008080, 0x02000080, 0x00000000,
	0x00000080, 0x00008002, 0x02008082, 0x02000080,
	0x02000002, 0x00000080, 0x00000000, 0x02008002,
	0x02000082, 0x00008000, 0x02000000, 0x02008082,
	0x00000002, 0x00008082, 0x00008080, 0x02000002,
	0x02008000, 0x02000082, 0x00000082, 0x02008000,
	0x00008082, 0x00000002, 0x02008002, 0x00008080,

	0x00000040, 0x00820040, 0x00820000, 0x10800040,
	0x00020000, 0x00000040, 0x10000000, 0x00820000,
	0x10020040, 0x00020000, 0x00800040, 0x10020040,
	0x10800040, 0x10820000, 0x00020040, 0x10000000,
	0x00800000, 0x10020000, 0x10020000, 0x00000000,
	0x10000040, 0x10820040, 0x10820040, 0x00800040,
	0x10820000, 0x10000040, 0x00000000, 0x10800000,
	0x00820040, 0x00800000, 0x10800000, 0x00020040,
	0x00020000, 0x10800040, 0x00000040, 0x00800000,
	0x10000000, 0x00820000, 0x10800040, 0x10020040,
	0x00800040, 0x10000000, 0x10820000, 0x00820040,
	0x10020040, 0x00000040, 0x00800000, 0x10820000,
	0x10820040, 0x00020040, 0x10800000, 0x10820040,
	0x00820000, 0x00000000, 0x10020000, 0x10800000,
	0x00020040, 0x00800040, 0x10000040, 0x00020000,
	0x00000000, 0x10020000, 0x00820040, 0x10000040,

	0x00080000, 0x81080000, 0x81000200, 0x00000000,
	0x00000200, 0x81000200, 0x80080200, 0x01080200,
	0x81080200, 0x00080000, 0x00000000, 0x81000000,
	0x80000000, 0x01000000, 0x81080000, 0x80000200,
	0x01000200, 0x80080200, 0x80080000, 0x01000200,
	0x81000000, 0x01080000, 0x01080200, 0x80080000,
	0x01080000, 0x00000200, 0x80000200, 0x81080200,
	0x00080200, 0x80000000, 0x01000000, 0x00080200,
	0x01000000, 0x00080200, 0x00080000, 0x81000200,
	0x81000200, 0x81080000, 0x81080000, 0x80000000,
	0x80080000, 0x01000000, 0x01000200, 0x00080000,
	0x01080200, 0x80000200, 0x80080200, 0x01080200,
	0x80000200, 0x81000000, 0x81080200, 0x01080000,
	0x00080200, 0x00000000, 0x80000000, 0x81080200,
	0x00000000, 0x80080200, 0x01080000, 0x00000200,
	0x81000000, 0x01000200, 0x00000200, 0x80080000 };

/* S-boxes 2, 4, 6, 8, plus P permutation, rotated */
static PGPUInt32 const SP1[512] = {
	0x20042008, 0x20002000, 0x00002000, 0x00042008,
	0x00040000, 0x00000008, 0x20040008, 0x20002008,
	0x20000008, 0x20042008, 0x20042000, 0x20000000,
	0x20002000, 0x00040000, 0x00000008, 0x20040008,
	0x00042000, 0x00040008, 0x20002008, 0x00000000,
	0x20000000, 0x00002000, 0x00042008, 0x20040000,
	0x00040008, 0x20000008, 0x00000000, 0x00042000,
	0x00002008, 0x20042000, 0x20040000, 0x00002008,
	0x00000000, 0x00042008, 0x20040008, 0x00040000,
	0x20002008, 0x20040000, 0x20042000, 0x00002000,
	0x20040000, 0x20002000, 0x00000008, 0x20042008,
	0x00042008, 0x00000008, 0x00002000, 0x20000000,
	0x00002008, 0x20042000, 0x00040000, 0x20000008,
	0x00040008, 0x20002008, 0x20000008, 0x00040008,
	0x00042000, 0x00000000, 0x20002000, 0x00002008,
	0x20000000, 0x20040008, 0x20042008, 0x00042000,

	0x40200800, 0x40000820, 0x40000820, 0x00000020,
	0x00200820, 0x40200020, 0x40200000, 0x40000800,
	0x00000000, 0x00200800, 0x00200800, 0x40200820,
	0x40000020, 0x00000000, 0x00200020, 0x40200000,
	0x40000000, 0x00000800, 0x00200000, 0x40200800,
	0x00000020, 0x00200000, 0x40000800, 0x00000820,
	0x40200020, 0x40000000, 0x00000820, 0x00200020,
	0x00000800, 0x00200820, 0x40200820, 0x40000020,
	0x00200020, 0x40200000, 0x00200800, 0x40200820,
	0x40000020, 0x00000000, 0x00000000, 0x00200800,
	0x00000820, 0x00200020, 0x40200020, 0x40000000,
	0x40200800, 0x40000820, 0x40000820, 0x00000020,
	0x40200820, 0x40000020, 0x40000000, 0x00000800,
	0x40200000, 0x40000800, 0x00200820, 0x40200020,
	0x40000800, 0x00000820, 0x00200000, 0x40200800,
	0x00000020, 0x00200000, 0x00000800, 0x00200820,

	0x08000004, 0x08100000, 0x00001000, 0x08101004,
	0x08100000, 0x00000004, 0x08101004, 0x00100000,
	0x08001000, 0x00101004, 0x00100000, 0x08000004,
	0x00100004, 0x08001000, 0x08000000, 0x00001004,
	0x00000000, 0x00100004, 0x08001004, 0x00001000,
	0x00101000, 0x08001004, 0x00000004, 0x08100004,
	0x08100004, 0x00000000, 0x00101004, 0x08101000,
	0x00001004, 0x00101000, 0x08101000, 0x08000000,
	0x08001000, 0x00000004, 0x08100004, 0x00101000,
	0x08101004, 0x00100000, 0x00001004, 0x08000004,
	0x00100000, 0x08001000, 0x08000000, 0x00001004,
	0x08000004, 0x08101004, 0x00101000, 0x08100000,
	0x00101004, 0x08101000, 0x00000000, 0x08100004,
	0x00000004, 0x00001000, 0x08100000, 0x00101004,
	0x00001000, 0x00100004, 0x08001004, 0x00000000,
	0x08101000, 0x08000000, 0x00100004, 0x08001004,

	0x04000410, 0x00000400, 0x00010000, 0x04010410,
	0x04000000, 0x04000410, 0x00000010, 0x04000000,
	0x00010010, 0x04010000, 0x04010410, 0x00010400,
	0x04010400, 0x00010410, 0x00000400, 0x00000010,
	0x04010000, 0x04000010, 0x04000400, 0x00000410,
	0x00010400, 0x00010010, 0x04010010, 0x04010400,
	0x00000410, 0x00000000, 0x00000000, 0x04010010,
	0x04000010, 0x04000400, 0x00010410, 0x00010000,
	0x00010410, 0x00010000, 0x04010400, 0x00000400,
	0x00000010, 0x04010010, 0x00000400, 0x00010410,
	0x04000400, 0x00000010, 0x04000010, 0x04010000,
	0x04010010, 0x04000000, 0x00010000, 0x04000410,
	0x00000000, 0x04010410, 0x00010010, 0x04000010,
	0x04010000, 0x04000400, 0x04000410, 0x00000000,
	0x04010410, 0x00010400, 0x00010400, 0x00000410,
	0x00000410, 0x00010010, 0x04000000, 0x04010400 };

/*
 * This encryption function is fairly clever in the way it does its
 * s-box lookup.  The S-boxes are indexed by bytes, rather than
 * words, because that's faster on many machines, and shifting
 * everything two bits to do the multiply by 4 is trivial.
 * Then, the indexing into the various S boxes is done by
 * adding the appropriate offset bits into the key array, so the
 * addition is done by the XOR with the key rather than having to
 * be done explicitly here.
 */
static void
des3DES (PGPByte const inblock[8], PGPByte outblock[8], PGPUInt32 const *keys)
{
	PGPUInt32 s, t, right, leftt;
	int round, iterate;
	
	leftt	= ((PGPUInt32)inblock[0] << 24)
                | ((PGPUInt32)inblock[1] << 16)
                | ((PGPUInt32)inblock[2] << 8)
                |  (PGPUInt32)inblock[3];
	right	= ((PGPUInt32)inblock[4] << 24)
                | ((PGPUInt32)inblock[5] << 16)
                | ((PGPUInt32)inblock[6] << 8)
                |  (PGPUInt32)inblock[7];

	/* Initial permutation IP */
	t = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
	right ^= t;
	leftt ^= (t << 4);
	t = ((leftt >> 16) ^ right) & 0x0000ffffL;
	right ^= t;
	leftt ^= (t << 16);
	t = ((right >> 2) ^ leftt) & 0x33333333L;
	leftt ^= t;
	right ^= (t << 2);
	t = ((right >> 8) ^ leftt) & 0x00ff00ffL;
	leftt ^= t;
	right ^= (t << 8);
	leftt = ((leftt >> 1) | (leftt << 31));
	t = (leftt ^ right) & 0x55555555L;
	leftt ^= t;
	right ^= t;
	right = ((right >> 1) | (right << 31));

	/* The main encryption loop */
	iterate = 3;
	goto Des0;
	do {
		t = right;
		right = leftt;
		leftt = t;
Des0:	
		for (round = 0; round < 8; round++) {
			s  = (right & 0xfcfcfcfc) ^ keys[0];
			t  = (((right >> 28) | (right << 4)) & 0xfcfcfcfc)
				^ keys[1];
			leftt ^= *(PGPUInt32 *)((char *)SP0+( s        & 0x3fc))
			       ^ *(PGPUInt32 *)((char *)SP0+((s >> 8 ) & 0x3fc))

⌨️ 快捷键说明

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