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

📄 crypto.c

📁 一个提供档案及Partition作加解密的程式支援以下的加密演算法AESBlowfishCAST5SerpentTriple DESTwofishAES-BlowfishAES-TwofishAES-
💻 C
📖 第 1 页 / 共 2 页
字号:
/* The source code contained in this file has been derived from the source code
   of Encryption for the Masses 2.02a by Paul Le Roux. Modifications and
   additions to that source code contained in this file are Copyright (c) 2004-2005
   TrueCrypt Foundation and Copyright (c) 2004 TrueCrypt Team. Unmodified
   parts are Copyright (c) 1998-99 Paul Le Roux. This is a TrueCrypt Foundation
   release. Please see the file license.txt for full license details. */

#include "TCdefs.h"
#include "crypto.h"
#include "random.h"
#include "crc.h"

/* Update the following when adding a new cipher or EA:

   Crypto.h:
     ID #define
     MAX_EXPANDED_KEY #define

   Crypto.c:
     Ciphers[]
     EncryptionAlgorithms[]
     CipherInit()
     EncipherBlock()
     DecipherBlock()
*/

// Cipher configuration
static Cipher Ciphers[] =
{
//	  ID		Name			Block size	Key size	Key schedule size
	{ AES,		"AES",			16,			32,			sizeof(aes_encrypt_ctx)+sizeof(aes_decrypt_ctx)	},
	{ BLOWFISH,	"Blowfish",		8,			56,			4168											},
	{ CAST,		"CAST5",		8,			16,			128												},
	{ DES56,	"DES",			8,			7,			128												},
	{ SERPENT,	"Serpent",		16,			32,			140*4											},
	{ TRIPLEDES,"Triple DES",	8,			7*3,		128*3											},
	{ TWOFISH,	"Twofish",		16,			32,			TWOFISH_KS										},
	{ 0,		0,				0,			0,			0												}
};

// Encryption algorithm configuration
static EncryptionAlgorithm EncryptionAlgorithms[] =
{
	//  Cipher(s)                     Mode
	{ { 0,						0 } , 0			},	// (must be null)
	{ { AES,					0 } , CBC		},	// AES
	{ { BLOWFISH,				0 } , CBC		},	// Blowfish
	{ { CAST,					0 } , CBC		},	// CAST5
	{ { SERPENT,				0 } , CBC		},	// Serpent
	{ { TRIPLEDES,				0 } , CBC		},	// Triple DES
	{ { TWOFISH,				0 } , CBC		},	// Twofish
	{ { BLOWFISH, AES,			0 } , INNER_CBC },	// AES-Blowfish
	{ { SERPENT, BLOWFISH, AES,	0 } , INNER_CBC },	// AES-Blowfish-Serpent
	{ { TWOFISH, AES,			0 } , OUTER_CBC },	// AES-Twofish
	{ { SERPENT, TWOFISH, AES,	0 } , OUTER_CBC },	// AES-Twofish-Serpent
	{ { AES, SERPENT,			0 } , OUTER_CBC },	// Serpent-AES
	{ { AES, TWOFISH, SERPENT,	0 } , OUTER_CBC },	// Serpent-Twofish-AES
	{ { SERPENT, TWOFISH,		0 } , OUTER_CBC },	// Twofish-Serpent
	{ { 0,						0 } , 0			}	// (must be null)
};


void CipherInit (int cipher, unsigned char *key, unsigned char *ks)
{
	switch (cipher)
	{
	case BLOWFISH:
		BF_set_key ((BF_KEY *)ks, CipherGetKeySize(BLOWFISH), key);
		break;

	case AES:
		aes_encrypt_key(key, CipherGetKeySize(AES), (aes_encrypt_ctx *) ks);
		aes_decrypt_key(key, CipherGetKeySize(AES), (aes_decrypt_ctx *) (ks + sizeof(aes_encrypt_ctx)));
		break;

	case DES56:
		des_key_sched ((des_cblock *) key, (struct des_ks_struct *) ks);
		break;

	case CAST:
		CAST_set_key((CAST_KEY *) ks, CipherGetKeySize(CAST), key);
		break;

	case SERPENT:
		serpent_set_key (key, CipherGetKeySize(SERPENT) * 8, ks);
		break;

	case TRIPLEDES:
		des_key_sched ((des_cblock *) key, (struct des_ks_struct *) ks);
		des_key_sched ((des_cblock *) ((char*)(key)+8), (struct des_ks_struct *) (ks + CipherGetKeyScheduleSize (DES56)));
		des_key_sched ((des_cblock *) ((char*)(key)+16), (struct des_ks_struct *) (ks + CipherGetKeyScheduleSize (DES56) * 2));
		break;

	case TWOFISH:
		twofish_set_key ((TwofishInstance *)ks, (const u4byte *)key, CipherGetKeySize(TWOFISH) * 8);
		break;

	}
}

void EncipherBlock(int cipher, void *data, void *ks)
{
	switch (cipher)
	{
	case BLOWFISH:		BF_encrypt (data, ks); break;
	case AES:			aes_encrypt (data, data, ks); break;
	case DES56:			des_encrypt (data, ks, 1); break;
	case CAST:			CAST_ecb_encrypt (data, data, ks, 1); break;
	case SERPENT:		serpent_encrypt (data, data, ks); break;
	case TRIPLEDES:		des_ecb3_encrypt (data, data, ks,
						(void*)((char*) ks + CipherGetKeyScheduleSize (DES56)), (void*)((char*) ks + CipherGetKeyScheduleSize (DES56) * 2), 1); break;
	case TWOFISH:		twofish_encrypt (ks, data, data); break;
	}
}

void DecipherBlock(int cipher, void *data, void *ks)
{
	switch (cipher)
	{
	case BLOWFISH:	BF_decrypt (data, ks); break;
	case AES:		aes_decrypt (data, data, (void *) ((char *) ks + sizeof(aes_encrypt_ctx))); break;
	case DES56:		des_encrypt (data, ks, 0); break;
	case CAST:		CAST_ecb_encrypt (data, data, ks,0); break;
	case SERPENT:	serpent_decrypt (data, data, ks); break;
	case TRIPLEDES:	des_ecb3_encrypt (data, data, ks,
					(void*)((char*) ks + CipherGetKeyScheduleSize (DES56)),
					(void*)((char*) ks + CipherGetKeyScheduleSize (DES56) * 2), 0); break;
	case TWOFISH:	twofish_decrypt (ks, data, data); break;
	}
}

// Ciphers support

Cipher *CipherGet (int id)
{
	int i;
	for (i = 0; Ciphers[i].Id != 0; i++)
		if (Ciphers[i].Id == id)
			return &Ciphers[i];

	return 0;
}

char *CipherGetName (int cipherId)
{
	return CipherGet (cipherId) -> Name;
}

int CipherGetBlockSize (int cipherId)
{
	return CipherGet (cipherId) -> BlockSize;
}

int CipherGetKeySize (int cipherId)
{
	return CipherGet (cipherId) -> KeySize;
}

int CipherGetKeyScheduleSize (int cipherId)
{
	return CipherGet (cipherId) -> KeyScheduleSize;
}


// Encryption algorithms support

int EAGetFirst ()
{
	return 1;
}

// Returns number of EAs
int EAGetCount (void)
{
	int ea, count = 0;

	for (ea = EAGetFirst (); ea != 0; ea = EAGetNext (ea))
	{
		count++;
	}
	return count;
}

int EAGetNext (int previousEA)
{
	int id = previousEA + 1;
	if (EncryptionAlgorithms[id].Ciphers[0] != 0) return id;
	return 0;
}

void EAInit (int ea, unsigned char *key, unsigned char *ks)
{
	int i = 0, c;

	for (c = EAGetFirstCipher (ea); c != 0; c = EAGetNextCipher (ea, c))
	{
		CipherInit (c, key, ks);

		key += CipherGetKeySize (c);
		ks += CipherGetKeyScheduleSize (c);
	}
}

// Returns name of EA, cascaded cipher names are separated by hyphens
char *EAGetName (char *buf, int ea)
{
	int i = EAGetLastCipher(ea);
	strcpy (buf, CipherGetName (i));

	while (i = EAGetPreviousCipher(ea, i))
	{
		strcat (buf, "-");
		strcat (buf, CipherGetName (i));
	}

	return buf;
}

// Returns sum of key sizes of all EA ciphers
int EAGetKeySize (int ea)
{
	int i = EAGetFirstCipher(ea);
	int size = CipherGetKeySize (i);

	while (i = EAGetNextCipher(ea, i))
	{
		size += CipherGetKeySize (i);
	}

	return size;
}

// Returns the mode of operation of the whole EA
int EAGetMode (int ea)
{
	return (EncryptionAlgorithms[ea].Mode);
}

// Returns the name of the mode of operation of the whole EA
char *EAGetModeName (char *name, int ea, BOOL capitalLetters)
{
	char eaName[100];

	switch (EncryptionAlgorithms[ea].Mode)
	{
	case CBC:
		EAGetName (eaName, ea);

		if (strcmp (eaName, "Triple DES") == 0)
			sprintf (name, "%s", capitalLetters ? "Outer-CBC" : "outer-CBC");
		else
			sprintf (name, "%s", "CBC");

		break;

	case OUTER_CBC:
		strcpy (name, capitalLetters ? "Outer-CBC" : "outer-CBC");
		break;

	case INNER_CBC:
		strcpy (name, capitalLetters ? "Inner-CBC" : "inner-CBC");
		break;

	default:
		strcpy (name, "[unknown]");
		break;
	}
	return name;
}

// Returns sum of key schedule sizes of all EA ciphers
int EAGetKeyScheduleSize (int ea)
{
	int i = EAGetFirstCipher(ea);
	int size = CipherGetKeyScheduleSize (i);

	while (i = EAGetNextCipher(ea, i))
	{
		size += CipherGetKeyScheduleSize (i);
	}

	return size;
}

// Returns largest key needed by all EAs
int EAGetLargestKey ()
{
	int ea, key = 0;

	for (ea = EAGetFirst (); ea != 0 ; ea = EAGetNext (ea))
	{
		if (EAGetKeySize (ea) >= key)
			key = EAGetKeySize (ea);
	}

	return key;
}

// Returns number of ciphers in EA
int EAGetCipherCount (int ea)
{
	int i = 0;
	while (EncryptionAlgorithms[ea].Ciphers[i++]);

	return i - 1;
}


int EAGetFirstCipher (int ea)
{
	return EncryptionAlgorithms[ea].Ciphers[0];
}

int EAGetLastCipher (int ea)
{
	int c, i = 0;
	while (c = EncryptionAlgorithms[ea].Ciphers[i++]);

	return EncryptionAlgorithms[ea].Ciphers[i - 2];
}

int EAGetNextCipher (int ea, int previousCipherId)
{
	int c, i = 0;
	while (c = EncryptionAlgorithms[ea].Ciphers[i++])
	{
		if (c == previousCipherId) 
			return EncryptionAlgorithms[ea].Ciphers[i];
	}

	return 0;
}

int EAGetPreviousCipher (int ea, int previousCipherId)
{
	int c, i = 0;

	if (EncryptionAlgorithms[ea].Ciphers[i++] == previousCipherId)
		return 0;

	while (c = EncryptionAlgorithms[ea].Ciphers[i++])
	{
		if (c == previousCipherId) 
			return EncryptionAlgorithms[ea].Ciphers[i - 2];
	}

	return 0;
}


// Hash support functions

char * get_hash_name (int pkcs5)
{
	switch (pkcs5)
	{
	case SHA1:		return "HMAC-SHA-1";
	case RIPEMD160:	return "HMAC-RIPEMD-160";
	default:		return "Unknown";
	}
}



PCRYPTO_INFO
crypto_open ()
{
	/* Do the crt allocation */
	PCRYPTO_INFO cryptoInfo = TCalloc (sizeof (CRYPTO_INFO));
#ifndef DEVICE_DRIVER
	VirtualLock (cryptoInfo, sizeof (CRYPTO_INFO));
#endif

	if (cryptoInfo == NULL)
		return NULL;

	cryptoInfo->ea = -1;
	return cryptoInfo;
}

void
crypto_loadkey (PKEY_INFO keyInfo, char *lpszUserKey, int nUserKeyLen)
{
	keyInfo->keyLength = nUserKeyLen;
	burn (keyInfo->userKey, sizeof (keyInfo->userKey));
	memcpy (keyInfo->userKey, lpszUserKey, nUserKeyLen);
}

void
crypto_close (PCRYPTO_INFO cryptoInfo)
{
	burn (cryptoInfo, sizeof (CRYPTO_INFO));
#ifndef DEVICE_DRIVER
	VirtualUnlock (cryptoInfo, sizeof (CRYPTO_INFO));
#endif
	TCfree (cryptoInfo);
}


// Initializes IV and whitening values for sector encryption/decryption
static void 
InitSectorIVAndWhitening (unsigned __int64 secNo,
	int blockSize,
	unsigned long *iv,
	unsigned __int64 *ivSeed,
	unsigned long *whitening)
{
	unsigned __int64 iv64[4];
	unsigned long *iv32 = (unsigned long *) iv64;

	iv64[0] = ivSeed[0] ^ secNo;
	iv64[1] = ivSeed[1] ^ secNo;
	iv64[2] = ivSeed[2] ^ secNo;
	if (blockSize == 16)
	{
		iv64[3] = ivSeed[3] ^ secNo;
	}

	iv[0] = iv32[0];
	iv[1] = iv32[1];

	switch (blockSize)
	{
	case 16:

		// 128-bit block

		iv[2] = iv32[2];
		iv[3] = iv32[3];

		whitening[0] = crc32long ( &iv32[4] ) ^ crc32long ( &iv32[7] );
		whitening[1] = crc32long ( &iv32[5] ) ^ crc32long ( &iv32[6] );
		break;

⌨️ 快捷键说明

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