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

📄 unativecryptomodule.cpp

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		}

	#if !PGP_EXCEPTIONS
		if (error.IsntError())
	#endif	// !PGP_EXCEPTIONS
		{
			// Encrypt the session key with the key derived from passphrase.
			pgpClearMemory(pKeyInfo->encryptedKey.bytes, 
				sizeof(pKeyInfo->encryptedKey.bytes));

			pPassCipher->Encrypt(pCipher->Key().bytes, 
				pKeyInfo->encryptedKey.bytes, 
				pCipher->NumKeyBytes() / pCipher->NumEncryptBytes());

			// Construct the checkbytes.
			pgpClearMemory(pKeyInfo->checkBytes.bytes, 
				sizeof(pKeyInfo->checkBytes.bytes));

			pPassCipher->Encrypt(pPassCipher->Key().bytes, 
				pKeyInfo->checkBytes.bytes);
		}
	}
#if PGP_EXCEPTIONS
	catch (CComboError& caughtErr)
	{
		error = caughtErr;
	}
#endif	// PGP_EXCEPTIONS

	return error;
}

CComboError 
DecryptPassphraseKey(
	Crypto::KeyHandle				keyHandle, 
	const char						*passphrase, 
	const Crypto::PassphraseSalt	*pSalt, 
	const Crypto::PassphraseKeyInfo	*pKeyInfo)
{
	pgpAssertStrValid(passphrase);
	pgpAssertAddrValid(pSalt, Crypto::PassphraseSalt);
	pgpAssertAddrValid(pKeyInfo, Crypto::PassphraseKeyInfo);

	CComboError	error;
	EXTRACT_CIPHER(keyHandle)

#if PGP_EXCEPTIONS
	try
#endif	// PGP_EXCEPTIONS
	{
		// Create new cipher out of passphrase.
		CCipherWrapper	pPassCipher(pCipher->Algorithm());

	#if !PGP_EXCEPTIONS
		error = pPassCipher.Status();

		if (error.IsntError())
	#endif	// !PGP_EXCEPTIONS
		{
			PGPUInt16	hashReps	= pKeyInfo->hashReps;

		#if PGP_EXCEPTIONS
			HashSaltSchedulePassphrase(passphrase, pSalt, pPassCipher, 
				hashReps, FALSE);
		#else	// !PGP_EXCEPTIONS
			error = HashSaltSchedulePassphrase(passphrase, pSalt, 
				pPassCipher, hashReps, FALSE);
		#endif	// PGP_EXCEPTIONS
		}

	#if !PGP_EXCEPTIONS
		if (error.IsntError())
	#endif	// !PGP_EXCEPTIONS
		{
			// Verify that the passphrase is valid by examining check bytes.
			Crypto::CheckBytes	checkBytes;
			pgpClearMemory(checkBytes.bytes, sizeof(checkBytes.bytes));

			pPassCipher->Encrypt(pPassCipher->Key().bytes, checkBytes.bytes);

			if (!pgpMemoryEqual(checkBytes.bytes, 
				pKeyInfo->checkBytes.bytes, pCipher->NumEncryptBytes()))
			{
			#if PGP_EXCEPTIONS
				THROW_PGPERROR(kPGPClientError_BadDiskPassphrase);
			#else	// !PGP_EXCEPTIONS
				error.pgpErr = kPGPClientError_BadDiskPassphrase;
			#endif	// PGP_EXCEPTIONS
			}
		}

	#if !PGP_EXCEPTIONS
		if (error.IsntError())
	#endif	// !PGP_EXCEPTIONS
		{
			// Decrypt the encrypted session key.
			CSecureObject<Crypto::SymmetricKey>	pSessionKey;

		#if !PGP_EXCEPTIONS
			error = pSessionKey.Status();

			if (error.IsntError())
		#endif	// !PGP_EXCEPTIONS
			{
				pPassCipher->Decrypt(pKeyInfo->encryptedKey.bytes, 
					pSessionKey->bytes, pCipher->NumKeyBytes() / 
					pCipher->NumDecryptBytes());

				// Assign the final session key and salt to the keyholder.
				pCipher->AttachKey(*pSessionKey, *pSalt);
			}
		}
	}
#if PGP_EXCEPTIONS
	catch (CComboError& caughtErr)
	{
		error = caughtErr;
	}
#endif	// PGP_EXCEPTIONS

	return error;
}

CComboError 
GenerateNewSymmetricKey(
	Crypto::KeyHandle				keyHandle, 
	PGPUInt8						*randomData1, 
	PGPUInt8						*randomData2, 
	PGPUInt32						bytesRandomData, 
	const Crypto::PassphraseSalt	*pSalt)
{
	CComboError	error;
	EXTRACT_CIPHER(keyHandle)

	pgpAssertAddrValid(randomData1, PGPUInt8);
	pgpAssertAddrValid(randomData2, PGPUInt8);
	pgpAssertAddrValid(pSalt, Crypto::PassphraseSalt);

#if PGP_EXCEPTIONS
	try
#endif	// PGP_EXCEPTIONS
	{
		// Make sure we have enough random data.
		if (bytesRandomData < pCipher->NumKeyBytes())
		{
		#if PGP_EXCEPTIONS
			THROW_PGPERROR(kPGPError_BufferTooSmall);
		#else	// !PGP_EXCEPTIONS
			error.pgpErr = kPGPError_BufferTooSmall;
			return error;
		#endif	// PGP_EXCEPTIONS
		}

	#if !PGP_EXCEPTIONS
		if (error.IsntError())
	#endif	// !PGP_EXCEPTIONS
		{
			// Get buffer for keys.
			CSecureObject<Crypto::SymmetricKey>	pSymKey;

		#if !PGP_EXCEPTIONS
			error = pSymKey.Status();

			if (error.IsntError())
		#endif	// !PGP_EXCEPTIONS
			{
				// Create new cipher out of randomData2 to munge randomData1
				CCipherWrapper	pMungeCipher(pCipher->Algorithm());

			#if !PGP_EXCEPTIONS
				error = pMungeCipher.Status();

				if (error.IsntError())
			#endif	// !PGP_EXCEPTIONS
				{
					// Copy data for munge key.
					pgpCopyMemory(randomData2, pSymKey->bytes, 
						pMungeCipher->NumKeyBytes());
					pMungeCipher->AttachKey(*pSymKey, *pSalt);

					// Generate new session key using randomData1.
					pgpCopyMemory(randomData1, pSymKey->bytes, 
						pCipher->NumKeyBytes());

					// Munge the new session key.
					for (PGPUInt32 i = 0; i < 2; i++)
					{
						pMungeCipher->Encrypt(pSymKey->bytes, 
							pSymKey->bytes, pCipher->NumKeyBytes() / 
							pCipher->NumEncryptBytes());
					}

					// Assign the final session key and salt.
					pCipher->AttachKey(*pSymKey, *pSalt);
				}
			}
		}
	}
#if PGP_EXCEPTIONS
	catch (CComboError& caughtErr)
	{
		error = caughtErr;
	}
#endif	// PGP_EXCEPTIONS

	return error;
}

CComboError 
Export(
	Crypto::KeyHandle	keyHandle, 
	void				*buffer, 
	PGPUInt32			sizeBuffer)
{
	CComboError	error;
	EXTRACT_CIPHER(keyHandle);

#if PGP_EXCEPTIONS
	try
	{
		pCipher->ExportCipher(buffer, sizeBuffer);
	}
	catch (CComboError& caughtErr)
	{
		error = caughtErr;
	}
#else	// !PGP_EXCEPTIONS
	error = pCipher->ExportCipher(buffer, sizeBuffer);
#endif	// PGP_EXCEPTIONS

	return error;
}

CComboError 
Import(
	Crypto::KeyHandle	keyHandle, 
	const void			*buffer, 
	PGPUInt32			sizeBuffer)
{
	CComboError	error;
	EXTRACT_CIPHER(keyHandle);

#if PGP_EXCEPTIONS
	try
	{
		pCipher->ImportCipher(buffer, sizeBuffer);
	}
	catch (CComboError& caughtErr)
	{
		error = caughtErr;
	}
#else	// !PGP_EXCEPTIONS
	error = pCipher->ImportCipher(buffer, sizeBuffer);
#endif	// PGP_EXCEPTIONS

	return error;
}

void 
EncryptBlock(
	const CCipher	*pCipher, 
	PGPUInt64		blockNumber, 
	const PGPUInt32	*inBlock, 
	PGPUInt32		*outBlock)
{
	pgpAssertAddrValid(pCipher, CCipher);
	pgpAssert(pCipher->IsKeyAttached());
	pgpAssertAddrValid(inBlock, PGPUInt32);
	pgpAssertAddrValid(outBlock, PGPUInt32);
	pgpAssert(pCipher->NumIvsNeeded()%2 == 0);

	PGPInt32	i, j;
	PGPInt32	halfIvs	= pCipher->NumIvsNeeded() / 2;
	PGPUInt32	ivs[8], sums[4];

	pgpAssert(halfIvs <= 4);	// if not so, bump up size of above arrays

	for (i = 0; i < halfIvs; i++)
	{
		sums[i] = pCipher->Salt().dwords[i] + 
			UMath::GetHighDWord(blockNumber) + 
			UMath::GetLowDWord(blockNumber);
	}

	for (i = 0; i < kBlockSizeIn32 - halfIvs; i++)
	{
		// simple Fletcher checksum of block
		sums[halfIvs - 1] += inBlock[i];

		for (j = halfIvs - 2; j >= 0; j--)
		{
			sums[j] += sums[j+1];
		}
	}

	for (i = 0; i < halfIvs; i++)
	{
		ivs[i] = sums[i] ^ inBlock[kBlockSizeIn32 - halfIvs + i];
	}

	for (i = 0; i < halfIvs; i++)
	{
		ivs[i + halfIvs] = ~ivs[i];
	}

	pCipher->EncryptCFBdbl(ivs, inBlock, outBlock, 
		Crypto::kCipherBlockSize/(pCipher->NumEncryptBytes()*2));

	for (i = 0; i < halfIvs; i++)
	{
		outBlock[kBlockSizeIn32 - halfIvs + i] ^= sums[i];
	}
}

void 
DecryptBlock(
	const CCipher	*pCipher, 
	PGPUInt64		blockNumber, 
	const PGPUInt32	*inBlock, 
	PGPUInt32		*outBlock)
{
	pgpAssertAddrValid(pCipher, CCipher);
	pgpAssert(pCipher->IsKeyAttached());
	pgpAssertAddrValid(inBlock, PGPUInt32);
	pgpAssertAddrValid(outBlock, PGPUInt32);
	pgpAssert(pCipher->NumIvsNeeded()%2 == 0);

	PGPInt32	i, j;
	PGPInt32	halfIvs	= pCipher->NumIvsNeeded() / 2;
	PGPUInt32	ivs[8];

	pgpAssert(halfIvs <= 4);	// if not so, bump up size of above arrays

	PGPUInt32	kSplitPointIn32;
	size_t		kBytesBeforeSplit;
	size_t		kBytesAfterSplit;

	kSplitPointIn32		= kBlockSizeIn32 / 2;
	kBytesBeforeSplit	= kSplitPointIn32 * sizeof(PGPUInt32);
	kBytesAfterSplit	= (kBlockSizeIn32 - kSplitPointIn32) * 
		sizeof(PGPUInt32);

	// This must be done in two halves to recover the IV.
	for (i = 0; i < halfIvs*2; i++)
	{
		ivs[i] = inBlock[kSplitPointIn32 - halfIvs*2 + i];
	}

	pCipher->DecryptCFBdbl(ivs, inBlock + kSplitPointIn32, 
		outBlock + kSplitPointIn32, 
		kBytesAfterSplit/(pCipher->NumDecryptBytes()*2));

	for (i = 0; i < halfIvs; i++)
	{
		ivs[i] = outBlock[kBlockSizeIn32 - halfIvs + i];
	}

	for (i = 0; i < halfIvs; i++)
	{
		ivs[i + halfIvs] = ~ivs[i];
	}

	pCipher->DecryptCFBdbl(ivs, inBlock, outBlock, 
		kBytesBeforeSplit/(pCipher->NumDecryptBytes()*2));

	// Undo the checksum.
	for (i = 0; i < halfIvs; i++)
	{
		ivs[i] = pCipher->Salt().dwords[i] + 
			UMath::GetHighDWord(blockNumber) + 
			UMath::GetLowDWord(blockNumber);
	}

	for (i = 0; i < kBlockSizeIn32 - halfIvs; i++)
	{
		// simple Fletcher checksum of block
		ivs[halfIvs - 1] += outBlock[i];

		for (j = halfIvs - 2; j >= 0; j--)
		{
			ivs[j] += ivs[j+1];
		}
	}
	
	for (i = 0; i < halfIvs; i++)
	{
		outBlock[kBlockSizeIn32 - halfIvs + i] ^= ivs[i];
	}
}

SMART_ERROR 
HashSaltSchedulePassphrase(
	const char						*passphrase, 
	const Crypto::PassphraseSalt	*pSalt, 
	CCipher							*pCipher, 
	PGPUInt16&						hashReps, 
	PGPBoolean						generateNewHashReps)
{
	pgpAssertStrValid(passphrase);
	pgpAssertAddrValid(pSalt, Crypto::PassphraseSalt);
	pgpAssertAddrValid(pCipher, CCipher);

	SMART_ERROR_DECLARE

	// Get secure objects.
	CSecureObject<CSHA>					pHasher;
	CSecureObject<Crypto::SymmetricKey>	pNewKey;
	CSecureObject<CSHA::Digest>			pHashResult;

#if !PGP_EXCEPTIONS
	error = pHasher.Status();

	if (error.IsntError())
		error = pNewKey.Status();

	if (error.IsntError())
		error = pHashResult.Status();

	if (error.IsntError())
#endif	// !PGP_EXCEPTIONS
	{
		// Generate key material.
		PGPUInt32	bytesNeeded	= pCipher->NumKeyBytes();
		PGPUInt32	offset		= 0;		// offset into output buffer

		while (bytesNeeded > 0)
		{
			// # bytes key material we need this iteration.
			PGPUInt32	bytesThisTime	= pgpMin(
				sizeof(pHashResult->bytes), bytesNeeded);

			// Init hash for this new round.
			pHasher->Init();

			// Update with previous hash result if not on first hash.
			if (offset > 0)
			{
				pHasher->Update(pHashResult->bytes, 
					sizeof(pHashResult->bytes));
			}

			// Update with the bare passphrase.
			pHasher->Update(reinterpret_cast<const PGPUInt8 *>(passphrase), 
				strlen(passphrase));

			// Save the hashed passphrase for use below.
			pHasher->Final(pHashResult.Get());

			// Re-initialize the hash and update with the salt.
			pHasher->Init();
			pHasher->Update(pSalt->bytes, pCipher->NumSaltBytes());

			// Hash in the hashed passphrase a number of times.
			PGPUInt8	j;
			PGPUInt16	i;

			if (generateNewHashReps && (offset == 0))
			{
				// We need to calculate how many times.
				PGPUInt64 endTicks	= UTime::GetSystemTicks() + 
					kMaxMsTimeForHash;

				for (i = 0, j = 0; (UTime::GetSystemTicks() < 
					endTicks) && (i < kMaxHashReps); i++, j++)
				{
					pHasher->Update(pHashResult->bytes, bytesThisTime);
					pHasher->Update(&j, 1);
				}

				hashReps = i;
			}
			else
			{
				// We already know how many times.
				for (i = 0, j = 0; i < hashReps; i++, j++)
				{
					pHasher->Update(pHashResult->bytes, bytesThisTime);
					pHasher->Update(&j, 1);
				}
			}

			// Finalize the hash.
			pHasher->Final(pHashResult.Get());

			// Copy the newly generated key bytes to the output buffer.
			pgpCopyMemory(pHashResult->bytes, pNewKey->bytes + offset, 
				bytesThisTime);

			bytesNeeded -= bytesThisTime;
			offset += bytesThisTime;
		}

		// Initialize the cipher with the final key.
		pCipher->AttachKey(*pNewKey, *pSalt);
	}

	SMART_ERROR_RETURN
}

_UNNAMED_END


// UNativeCryptoModule functions

void 
UNativeCryptoModule::GetVTable(Crypto::CipherVTable& vTable)
{
	vTable.pfnGetAlgorithmIdString	= GetAlgorithmIdString;

	vTable.pfnGetEncryptSize			= GetEncryptSize;
	vTable.pfnGetDecryptSize			= GetDecryptSize;
	vTable.pfnGetKeySize				= GetKeySize;
	vTable.pfnGetNeededRandomDataSize	= GetNeededRandomDataSize;
	vTable.pfnGetSizeForExport			= GetSizeForExport;

	vTable.pfnValidate	= Validate;

	vTable.pfnInit		= Init;
	vTable.pfnCleanup	= Cleanup;

	vTable.pfnAttachSymmetricKey	= AttachSymmetricKey;
	vTable.pfnGetSymmetricKey		= GetSymmetricKey;
	vTable.pfnGetSalt				= GetSalt;

	vTable.pfnFlipKeyBytes	= FlipKeyBytes;

	vTable.pfnEncrypt		= Encrypt;
	vTable.pfnDecrypt		= Decrypt;
	vTable.pfnEncryptCFB	= EncryptCFB;
	vTable.pfnDecryptCFB	= DecryptCFB;

	vTable.pfnEncryptPassphraseKey		= EncryptPassphraseKey;
	vTable.pfnGenerateNewSymmetricKey	= GenerateNewSymmetricKey;
	vTable.pfnDecryptPassphraseKey		= DecryptPassphraseKey;
	vTable.pfnExport					= Export;
	vTable.pfnImport					= Import;
}

⌨️ 快捷键说明

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