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

📄 crypto.c

📁 功能强大的开源加密软件。使用最新ieee-p1619标准
💻 C
📖 第 1 页 / 共 3 页
字号:
//              ciphers divisible by the largest block size used within the cascade)
void EncryptBuffer (unsigned __int8 *buf,
			   TC_LARGEST_COMPILER_UINT len,
			   PCRYPTO_INFO cryptoInfo)
{
	switch (cryptoInfo->mode)
	{
	case XTS:
		{
			unsigned __int8 *ks = cryptoInfo->ks;
			unsigned __int8 *ks2 = cryptoInfo->ks2;
			UINT64_STRUCT dataUnitNo;
			int cipher;

			// When encrypting/decrypting a buffer (typically a volume header) the sequential number
			// of the first XTS data unit in the buffer is always 0 and the start of the buffer is
			// always considered aligned with the start of a data unit.
			dataUnitNo.LowPart = 0;
			dataUnitNo.HighPart = 0;

			for (cipher = EAGetFirstCipher (cryptoInfo->ea);
				cipher != 0;
				cipher = EAGetNextCipher (cryptoInfo->ea, cipher))
			{
				EncryptBufferXTS (buf, len, &dataUnitNo, 0, ks, ks2, cipher);

				ks += CipherGetKeyScheduleSize (cipher);
				ks2 += CipherGetKeyScheduleSize (cipher);
			}
		}
		break;

#ifndef TC_NO_COMPILER_INT64
	case LRW:

		/* Deprecated/legacy */

		switch (CipherGetBlockSize (EAGetFirstCipher (cryptoInfo->ea)))
		{
		case 8:
			EncryptBufferLRW64 ((unsigned __int8 *)buf, (unsigned __int64) len, 1, cryptoInfo);
			break;

		case 16:
			EncryptBufferLRW128 ((unsigned __int8 *)buf, (unsigned __int64) len, 1, cryptoInfo);
			break;

		default:
			TC_THROW_FATAL_EXCEPTION;
		}
		break;

	case CBC:
	case INNER_CBC:
		{
			/* Deprecated/legacy */

			unsigned __int8 *ks = cryptoInfo->ks;
			int cipher;

			for (cipher = EAGetFirstCipher (cryptoInfo->ea);
				cipher != 0;
				cipher = EAGetNextCipher (cryptoInfo->ea, cipher))
			{
				EncryptBufferCBC ((unsigned __int32 *) buf,
					(unsigned int) len,
					ks,
					(unsigned __int32 *) cryptoInfo->k2,
					(unsigned __int32 *) &cryptoInfo->k2[8],
					0,
					cipher);

				ks += CipherGetKeyScheduleSize (cipher);
			}
		}
		break;

	case OUTER_CBC:

		/* Deprecated/legacy */

		EncryptBufferCBC ((unsigned __int32 *) buf,
			(unsigned int) len,
			cryptoInfo->ks,
			(unsigned __int32 *) cryptoInfo->k2,
			(unsigned __int32 *) &cryptoInfo->k2[8],
			cryptoInfo->ea,
			0);

		break;
#endif	// #ifndef TC_NO_COMPILER_INT64

	default:		
		// Unknown/wrong ID
		TC_THROW_FATAL_EXCEPTION;
	}
}

#ifndef TC_NO_COMPILER_INT64
// Converts a data unit number to the index of the first LRW block in the data unit.
// Note that the maximum supported volume size is 8589934592 GB  (i.e., 2^63 bytes).
unsigned __int64 DataUnit2LRWIndex (unsigned __int64 dataUnit, int blockSize, PCRYPTO_INFO ci)
{
	/* Deprecated/legacy */

	if (ci->hiddenVolume)
		dataUnit -= ci->hiddenVolumeOffset / ENCRYPTION_DATA_UNIT_SIZE;
	else
		dataUnit -= HEADER_SIZE / ENCRYPTION_DATA_UNIT_SIZE;	// Compensate for the volume header size

	switch (blockSize)
	{
	case 8:
		return (dataUnit << 6) | 1;

	case 16:
		return (dataUnit << 5) | 1;

	default:
		TC_THROW_FATAL_EXCEPTION;
	}

	return 0;
}
#endif	// #ifndef TC_NO_COMPILER_INT64


// buf:			data to be encrypted
// unitNo:		sequential number of the data unit with which the buffer starts
// nbrUnits:	number of data units in the buffer
void EncryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
{
	int ea = ci->ea;
	unsigned __int8 *ks = ci->ks;
	unsigned __int8 *ks2 = ci->ks2;
	int cipher;

#ifndef TC_NO_COMPILER_INT64
	void *iv = ci->k2;									// Deprecated/legacy
	unsigned __int64 unitNo = structUnitNo->Value;
	unsigned __int64 *iv64 = (unsigned __int64 *) iv;	// Deprecated/legacy
	unsigned __int32 sectorIV[4];						// Deprecated/legacy
	unsigned __int32 secWhitening[2];					// Deprecated/legacy
#endif

	switch (ci->mode)
	{
	case XTS:
		for (cipher = EAGetFirstCipher (ea); cipher != 0; cipher = EAGetNextCipher (ea, cipher))
		{
			EncryptBufferXTS (buf,
				nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
				structUnitNo,
				0,
				ks,
				ks2,
				cipher);

			ks += CipherGetKeyScheduleSize (cipher);
			ks2 += CipherGetKeyScheduleSize (cipher);
		}
		break;

#ifndef TC_NO_COMPILER_INT64
	case LRW:

		/* Deprecated/legacy */

		switch (CipherGetBlockSize (EAGetFirstCipher (ea)))
		{
		case 8:
			EncryptBufferLRW64 (buf,
				(unsigned __int64) nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
				DataUnit2LRWIndex (unitNo, 8, ci),
				ci);
			break;

		case 16:
			EncryptBufferLRW128 (buf,
				(unsigned __int64) nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
				DataUnit2LRWIndex (unitNo, 16, ci),
				ci);
			break;

		default:
			TC_THROW_FATAL_EXCEPTION;
		}
		break;

	case CBC:
	case INNER_CBC:

		/* Deprecated/legacy */

		while (nbrUnits--)
		{
			for (cipher = EAGetFirstCipher (ea); cipher != 0; cipher = EAGetNextCipher (ea, cipher))
			{
				InitSectorIVAndWhitening (unitNo, CipherGetBlockSize (cipher), sectorIV, iv64, secWhitening);

				EncryptBufferCBC ((unsigned __int32 *) buf,
					ENCRYPTION_DATA_UNIT_SIZE,
					ks,
					sectorIV,
					secWhitening,
					0,
					cipher);

				ks += CipherGetKeyScheduleSize (cipher);
			}
			ks -= EAGetKeyScheduleSize (ea);
			buf += ENCRYPTION_DATA_UNIT_SIZE;
			unitNo++;
		}
		break;

	case OUTER_CBC:

		/* Deprecated/legacy */

		while (nbrUnits--)
		{
			InitSectorIVAndWhitening (unitNo, CipherGetBlockSize (EAGetFirstCipher (ea)), sectorIV, iv64, secWhitening);

			EncryptBufferCBC ((unsigned __int32 *) buf,
				ENCRYPTION_DATA_UNIT_SIZE,
				ks,
				sectorIV,
				secWhitening,
				ea,
				0);

			buf += ENCRYPTION_DATA_UNIT_SIZE;
			unitNo++;
		}
		break;
#endif	// #ifndef TC_NO_COMPILER_INT64

	default:		
		// Unknown/wrong ID
		TC_THROW_FATAL_EXCEPTION;
	}
}

// DecryptBuffer
//
// buf:			data to be decrypted
// len:			number of bytes to decrypt; must be divisible by the block size (for cascaded
//              ciphers divisible by the largest block size used within the cascade)
void DecryptBuffer (unsigned __int8 *buf,
		TC_LARGEST_COMPILER_UINT len,
		PCRYPTO_INFO cryptoInfo)
{
	switch (cryptoInfo->mode)
	{
	case XTS:
		{
			unsigned __int8 *ks = cryptoInfo->ks + EAGetKeyScheduleSize (cryptoInfo->ea);
			unsigned __int8 *ks2 = cryptoInfo->ks2 + EAGetKeyScheduleSize (cryptoInfo->ea);
			UINT64_STRUCT dataUnitNo;
			int cipher;

			// When encrypting/decrypting a buffer (typically a volume header) the sequential number
			// of the first XTS data unit in the buffer is always 0 and the start of the buffer is
			// always considered aligned with the start of the data unit 0.
			dataUnitNo.LowPart = 0;
			dataUnitNo.HighPart = 0;

			for (cipher = EAGetLastCipher (cryptoInfo->ea);
				cipher != 0;
				cipher = EAGetPreviousCipher (cryptoInfo->ea, cipher))
			{
				ks -= CipherGetKeyScheduleSize (cipher);
				ks2 -= CipherGetKeyScheduleSize (cipher);

				DecryptBufferXTS (buf, len, &dataUnitNo, 0, ks, ks2, cipher);
			}
		}
		break;

#ifndef TC_NO_COMPILER_INT64
	case LRW:

		/* Deprecated/legacy */

		switch (CipherGetBlockSize (EAGetFirstCipher (cryptoInfo->ea)))
		{
		case 8:
			DecryptBufferLRW64 (buf, (unsigned __int64) len, 1, cryptoInfo);
			break;

		case 16:
			DecryptBufferLRW128 (buf, (unsigned __int64) len, 1, cryptoInfo);
			break;

		default:
			TC_THROW_FATAL_EXCEPTION;
		}
		break;

	case CBC:
	case INNER_CBC:
		{
			/* Deprecated/legacy */

			unsigned __int8 *ks = cryptoInfo->ks + EAGetKeyScheduleSize (cryptoInfo->ea);
			int cipher;
			for (cipher = EAGetLastCipher (cryptoInfo->ea);
				cipher != 0;
				cipher = EAGetPreviousCipher (cryptoInfo->ea, cipher))
			{
				ks -= CipherGetKeyScheduleSize (cipher);

				DecryptBufferCBC ((unsigned __int32 *) buf,
					(unsigned int) len,
					ks,
					(unsigned __int32 *) cryptoInfo->k2,
					(unsigned __int32 *) &cryptoInfo->k2[8],
					0,
					cipher);
			}
		}
		break;

	case OUTER_CBC:

		/* Deprecated/legacy */

		DecryptBufferCBC ((unsigned __int32 *) buf,
			(unsigned int) len,
			cryptoInfo->ks,
			(unsigned __int32 *) cryptoInfo->k2,
			(unsigned __int32 *) &cryptoInfo->k2[8],
			cryptoInfo->ea,
			0);

		break;
#endif	// #ifndef TC_NO_COMPILER_INT64

	default:		
		// Unknown/wrong ID
		TC_THROW_FATAL_EXCEPTION;
	}
}

// buf:			data to be decrypted
// unitNo:		sequential number of the data unit with which the buffer starts
// nbrUnits:	number of data units in the buffer
void DecryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
{
	int ea = ci->ea;
	unsigned __int8 *ks = ci->ks;
	unsigned __int8 *ks2 = ci->ks2;
	int cipher;

#ifndef TC_NO_COMPILER_INT64
	void *iv = ci->k2;									// Deprecated/legacy
	unsigned __int64 unitNo = structUnitNo->Value;
	unsigned __int64 *iv64 = (unsigned __int64 *) iv;	// Deprecated/legacy
	unsigned __int32 sectorIV[4];						// Deprecated/legacy
	unsigned __int32 secWhitening[2];					// Deprecated/legacy
#endif	// #ifndef TC_NO_COMPILER_INT64


	switch (ci->mode)
	{
	case XTS:
		ks += EAGetKeyScheduleSize (ea);
		ks2 += EAGetKeyScheduleSize (ea);

		for (cipher = EAGetLastCipher (ea); cipher != 0; cipher = EAGetPreviousCipher (ea, cipher))
		{
			ks -= CipherGetKeyScheduleSize (cipher);
			ks2 -= CipherGetKeyScheduleSize (cipher);

			DecryptBufferXTS (buf,
				nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
				structUnitNo,
				0,
				ks,
				ks2,
				cipher);
		}
		break;

#ifndef TC_NO_COMPILER_INT64
	case LRW:

		/* Deprecated/legacy */

		switch (CipherGetBlockSize (EAGetFirstCipher (ea)))
		{
		case 8:
			DecryptBufferLRW64 (buf,
				(unsigned __int64) nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
				DataUnit2LRWIndex (unitNo, 8, ci),
				ci);
			break;

		case 16:
			DecryptBufferLRW128 (buf,
				(unsigned __int64) nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
				DataUnit2LRWIndex (unitNo, 16, ci),
				ci);
			break;

		default:
			TC_THROW_FATAL_EXCEPTION;
		}
		break;

	case CBC:
	case INNER_CBC:

		/* Deprecated/legacy */

		while (nbrUnits--)
		{
			ks += EAGetKeyScheduleSize (ea);
			for (cipher = EAGetLastCipher (ea); cipher != 0; cipher = EAGetPreviousCipher (ea, cipher))
			{
				InitSectorIVAndWhitening (unitNo, CipherGetBlockSize (cipher), sectorIV, iv64, secWhitening);

				ks -= CipherGetKeyScheduleSize (cipher);

				DecryptBufferCBC ((unsigned __int32 *) buf,
					ENCRYPTION_DATA_UNIT_SIZE,
					ks,
					sectorIV,
					secWhitening,
					0,
					cipher);
			}
			buf += ENCRYPTION_DATA_UNIT_SIZE;
			unitNo++;
		}
		break;

	case OUTER_CBC:

		/* Deprecated/legacy */

		while (nbrUnits--)
		{
			InitSectorIVAndWhitening (unitNo, CipherGetBlockSize (EAGetFirstCipher (ea)), sectorIV, iv64, secWhitening);

			DecryptBufferCBC ((unsigned __int32 *) buf,
				ENCRYPTION_DATA_UNIT_SIZE,
				ks,
				sectorIV,
				secWhitening,
				ea,
				0);

			buf += ENCRYPTION_DATA_UNIT_SIZE;
			unitNo++;
		}
		break;
#endif // #ifndef TC_NO_COMPILER_INT64

	default:		
		// Unknown/wrong ID
		TC_THROW_FATAL_EXCEPTION;
	}
}


// Returns the maximum number of bytes necessary to be generated by the PBKDF2 (PKCS #5)
int GetMaxPkcs5OutSize (void)
{
	int size = 32;

#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif

	size = max (size, EAGetLargestKeyForMode (XTS) * 2);	// Sizes of primary + secondary keys

#ifndef TC_WINDOWS_BOOT
	size = max (size, LEGACY_VOL_IV_SIZE + EAGetLargestKeyForMode (LRW));		// Deprecated/legacy
	size = max (size, LEGACY_VOL_IV_SIZE + EAGetLargestKeyForMode (CBC));		// Deprecated/legacy
	size = max (size, LEGACY_VOL_IV_SIZE + EAGetLargestKeyForMode (OUTER_CBC));	// Deprecated/legacy
	size = max (size, LEGACY_VOL_IV_SIZE + EAGetLargestKeyForMode (INNER_CBC));	// Deprecated/legacy
#endif

	return size;
}


#else // TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE


#if !defined (TC_WINDOWS_BOOT_AES) && !defined (TC_WINDOWS_BOOT_SERPENT) && !defined (TC_WINDOWS_BOOT_TWOFISH)
#error No cipher defined
#endif

void EncipherBlock(int cipher, void *data, void *ks)
{
#ifdef TC_WINDOWS_BOOT_AES
	aes_encrypt (data, data, ks); 
#elif defined (TC_WINDOWS_BOOT_SERPENT)
	serpent_encrypt (data, data, ks);
#elif defined (TC_WINDOWS_BOOT_TWOFISH)
	twofish_encrypt (ks, data, data);
#endif
}

void DecipherBlock(int cipher, void *data, void *ks)
{
#ifdef TC_WINDOWS_BOOT_AES
	aes_decrypt (data, data, (aes_decrypt_ctx *) ((byte *) ks + sizeof(aes_encrypt_ctx))); 
#elif defined (TC_WINDOWS_BOOT_SERPENT)
	serpent_decrypt (data, data, ks);
#elif defined (TC_WINDOWS_BOOT_TWOFISH)
	twofish_decrypt (ks, data, data);
#endif
}

int EAGetFirst ()
{
	return 1;
}

int EAGetNext (int previousEA)
{
	return 0;
}

int EAInit (int ea, unsigned char *key, unsigned __int8 *ks)
{
#ifdef TC_WINDOWS_BOOT_AES

	aes_init();

	if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ks) != EXIT_SUCCESS)
		return ERR_CIPHER_INIT_FAILURE;
	if (aes_decrypt_key256 (key, (aes_decrypt_ctx *) (ks + sizeof (aes_encrypt_ctx))) != EXIT_SUCCESS)
		return ERR_CIPHER_INIT_FAILURE;

#elif defined (TC_WINDOWS_BOOT_SERPENT)
	serpent_set_key (key, 32 * 8, ks);
#elif defined (TC_WINDOWS_BOOT_TWOFISH)
	twofish_set_key ((TwofishInstance *)ks, (const u4byte *)key, 32 * 8);
#endif
	return ERR_SUCCESS;
}

int EAGetKeySize (int ea)
{
	return 32;
}

int EAGetFirstCipher (int ea)
{
	return 1;
}

void EncryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo)
{
	UINT64_STRUCT dataUnitNo;
	dataUnitNo.LowPart = 0; dataUnitNo.HighPart = 0;
	EncryptBufferXTS (buf, len, &dataUnitNo, 0, cryptoInfo->ks, cryptoInfo->ks2, 1);
}

void EncryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
{
	EncryptBufferXTS (buf, nbrUnits * ENCRYPTION_DATA_UNIT_SIZE, structUnitNo, 0, ci->ks, ci->ks2, 1);
}

void DecryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo)
{
	UINT64_STRUCT dataUnitNo;
	dataUnitNo.LowPart = 0; dataUnitNo.HighPart = 0;
	DecryptBufferXTS (buf, len, &dataUnitNo, 0, cryptoInfo->ks, cryptoInfo->ks2, 1);
}

void DecryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
{
	DecryptBufferXTS (buf, nbrUnits * ENCRYPTION_DATA_UNIT_SIZE, structUnitNo, 0, ci->ks, ci->ks2, 1);
}

#endif // TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE

⌨️ 快捷键说明

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