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

📄 ctwofishcipher.cpp

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 CPP
字号:
/*____________________________________________________________________________
		Copyright (C) 2002 PGP Corporation
        All rights reserved.

        $Id: CTwofishCipher.cpp,v 1.6 2002/08/06 20:10:19 dallen Exp $
____________________________________________________________________________*/

#include "pgpClassesConfig.h"

#include "CCRC32.h"
#include "CTwofishCipher.h"

_USING_PGP

// Externs

// For table verification only.
extern "C"	BYTE P8x8[2][256];


// Class CTwofishCipher member functions

CTwofishCipher::CTwofishCipher(PGPdiskEncryptionAlgorithm algorithm)
	: CCipher(algorithm), mIsKeyAttached(FALSE), mPCurKeyInfo(NULL)
{
	pgpAssert(algorithm == kPGPdiskTwoFishAlgorithm);

#if !PGP_EXCEPTIONS
	if (Status().IsntError())
		Status() = CCipher::Status();

	if (Status().IsntError())
		Status() = mKeyInfo1.Status();

	if (Status().IsntError())
		Status() = mKeyInfo2.Status();
#endif	// !PGP_EXCEPTIONS
}

SMART_ERROR 
CTwofishCipher::Validate() const
{
	SMART_ERROR_DECLARE

	if (!IsKeyAttached())
#if PGP_EXCEPTIONS
		THROW_PGPERROR(kPGPError_BadParams);
#else	// !PGP_EXCEPTIONS
		error.pgpErr = kPGPError_BadParams;

	if (error.IsntError())
#endif	// PGP_EXCEPTIONS
	{
		CCRC32	crc;

		crc.Continue(reinterpret_cast<const PGPUInt32 *>(P8x8), 
			sizeof(P8x8) / sizeof(PGPUInt32));

		if (crc.GetCRC() != ValidationCRC)
	#if PGP_EXCEPTIONS
			THROW_PGPERROR(kPGPError_CorruptData);
	#else	// !PGP_EXCEPTIONS
			error.pgpErr = kPGPError_CorruptData;
	#endif	// PGP_EXCEPTIONS
	}

	SMART_ERROR_RETURN
}

void 
CTwofishCipher::AttachKey(
	const Crypto::SymmetricKey&		key, 
	const Crypto::PassphraseSalt&	salt)
{
	mKeyInfo1.Wipe();
	mKeyInfo2.Wipe();

	mKeyInfo1->key	= key;
	mKeyInfo1->salt	= salt;

	// Initialize Twofish key instance.
	mKeyInfo1->keyInstance.direction	= DIR_ENCRYPT;
	mKeyInfo1->keyInstance.keyLen		= NumKeyBits();
	mKeyInfo1->keyInstance.numRounds	= TwofishGetNumRounds(NumKeyBits());

	pgpCopyMemory(key.bytes, mKeyInfo1->keyInstance.key32, NumKeyBytes());

	// Generate round subkeys.
	reKey(&mKeyInfo1->keyInstance);

	// Setup key 2.
	*mKeyInfo2 = *mKeyInfo1;
	mKeyInfo2.FlipBytes();

	mTrueIfUsingKey1 = TRUE;
	mPCurKeyInfo = mKeyInfo1.Get();

	mIsKeyAttached = TRUE;
}

void 
CTwofishCipher::FlipKeyBytes()
{
	pgpAssert(IsKeyAttached());

	mKeyInfo1.FlipBytes();
	mKeyInfo2.FlipBytes();

	if (mTrueIfUsingKey1)
	{
		mPCurKeyInfo = mKeyInfo2.Get();
		mTrueIfUsingKey1 = FALSE;
	}
	else
	{
		mPCurKeyInfo = mKeyInfo1.Get();
		mTrueIfUsingKey1 = TRUE;
	}
}

void 
CTwofishCipher::Encrypt(const void *in, void *out, PGPUInt32 numBlocks) const
{
	pgpAssert(IsKeyAttached());
	pgpAssertAddrValid(in, VoidAlign);
	pgpAssertAddrValid(out, VoidAlign);

	PGPUInt8	*dataIn		= static_cast<PGPUInt8 *>(const_cast<void *>(in));
	PGPUInt8	*dataOut	= static_cast<PGPUInt8 *>(out);

	cipherInstance	cipher;
	pgpClearMemory(&cipher, sizeof(cipher));

	cipher.mode = MODE_ECB;

	// BLOCK_SIZE is Twofish block size, not PGPdisk block size (duh).
	for (PGPUInt32 i = 0; i < numBlocks; i++)
	{
		blockEncrypt(&cipher, &mPCurKeyInfo->keyInstance, 
			dataIn + (i*NumEncryptBytes()), BLOCK_SIZE, 
			dataOut + (i*NumEncryptBytes()));
	}
}

void 
CTwofishCipher::Decrypt(const void *in, void *out, PGPUInt32 numBlocks) const
{
	pgpAssert(IsKeyAttached());
	pgpAssertAddrValid(in, VoidAlign);
	pgpAssertAddrValid(out, VoidAlign);

	PGPUInt8	*dataIn		= static_cast<PGPUInt8 *>(const_cast<void *>(in));
	PGPUInt8	*dataOut	= static_cast<PGPUInt8 *>(out);

	cipherInstance	cipher;
	pgpClearMemory(&cipher, sizeof(cipher));

	cipher.mode = MODE_ECB;

	// BLOCK_SIZE is Twofish block size, not PGPdisk block size (duh).
	for (PGPUInt32 i = 0; i < numBlocks; i++)
	{
		blockDecrypt(&cipher, &mPCurKeyInfo->keyInstance, 
			dataIn + (i*NumDecryptBytes()), BLOCK_SIZE, 
			dataOut + (i*NumDecryptBytes()));
	}
}

void 
CTwofishCipher::EncryptCFBdbl(
	PGPUInt32			ivs[], 
	const PGPUInt32*	src, 
	PGPUInt32*			dest, 
	PGPUInt32			len) const
{
	pgpAssert(IsKeyAttached());
	pgpAssertAddrValid(src, PGPUIn32);
	pgpAssertAddrValid(dest, PGPUIn32);

	while (len--) 
	{
		Encrypt(ivs, ivs);

		*dest++	= ivs[0]	^= *src++;
		*dest++	= ivs[1]	^= *src++;
		*dest++	= ivs[2]	^= *src++;
		*dest++	= ivs[3]	^= *src++;

		Encrypt(ivs + 4, ivs + 4);

		*dest++	= ivs[4]	^= *src++;
		*dest++	= ivs[5]	^= *src++;
		*dest++	= ivs[6]	^= *src++;
		*dest++	= ivs[7]	^= *src++;
	}
}

void 
CTwofishCipher::DecryptCFBdbl(
	PGPUInt32			ivs[], 
	const PGPUInt32*	src, 
	PGPUInt32*			dest, 
	PGPUInt32			len) const
{
	pgpAssert(IsKeyAttached());
	pgpAssertAddrValid(src, PGPUIn32);
	pgpAssertAddrValid(dest, PGPUIn32);

	PGPUInt32	out[8];

	while (len--)
	{
		Encrypt(ivs, out);

		*dest++	= out[0] ^ (ivs[0] = *src++);
		*dest++	= out[1] ^ (ivs[1] = *src++);
		*dest++	= out[2] ^ (ivs[2] = *src++);
		*dest++	= out[3] ^ (ivs[3] = *src++);

		Encrypt(ivs + 4, out + 4);

		*dest++	= out[4] ^ (ivs[4] = *src++);
		*dest++	= out[5] ^ (ivs[5] = *src++);
		*dest++	= out[6] ^ (ivs[6] = *src++);
		*dest++	= out[7] ^ (ivs[7] = *src++);
	}
}

SMART_ERROR 
CTwofishCipher::ExportCipher(void *buffer, PGPUInt32 sizeBuffer) const
{
	pgpAssert(IsKeyAttached());
	pgpAssertAddrValid(buffer, VoidAlign);

	SMART_ERROR_DECLARE

	if (sizeBuffer < SizeExportedCipher())
#if PGP_EXCEPTIONS
		THROW_PGPERROR(kPGPError_BufferTooSmall);
#else	// !PGP_EXCEPTIONS
		error.pgpErr = kPGPError_BufferTooSmall;

	if (error.IsntError())
#endif	// PGP_EXCEPTIONS
	{
		ExportedCipher	*pEC	= static_cast<ExportedCipher *>(buffer);

		pEC->key = mPCurKeyInfo->key;
		pEC->salt = mPCurKeyInfo->salt;
	}

	SMART_ERROR_RETURN
}

SMART_ERROR 
CTwofishCipher::ImportCipher(const void *buffer, PGPUInt32 sizeBuffer)
{
	pgpAssert(!IsKeyAttached());
	pgpAssertAddrValid(buffer, VoidAlign);

	SMART_ERROR_DECLARE

	if (sizeBuffer < SizeExportedCipher())
#if PGP_EXCEPTIONS
		THROW_PGPERROR(kPGPError_BufferTooSmall);
#else	// !PGP_EXCEPTIONS
		error.pgpErr = kPGPError_BufferTooSmall;

	if (error.IsntError())
#endif	// PGP_EXCEPTIONS

	{
		const ExportedCipher	*pEC	= 
			static_cast<const ExportedCipher *>(buffer);

		AttachKey(pEC->key, pEC->salt);
	}

	SMART_ERROR_RETURN
}

⌨️ 快捷键说明

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