📄 ccast5cipher.cpp
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: CCast5Cipher.cpp,v 1.7 2002/08/06 20:10:19 dallen Exp $
____________________________________________________________________________*/
#include "pgpClassesConfig.h"
#include "pgpDiskPubTypes.h"
#include "CCRC32.h"
#include "Cast5.h"
#include "Cast5Box.h"
#include "CCast5Cipher.h"
#include "pgpClientErrors.h"
_USING_PGP
// Class CCast5Cipher member functions
CCast5Cipher::CCast5Cipher(PGPdiskEncryptionAlgorithm algorithm)
: CCipher(algorithm), mIsKeyAttached(FALSE), mPCurKeyInfo(NULL)
{
pgpAssert((algorithm == kPGPdiskCAST5Algorithm) ||
(algorithm == kPGPdiskOldCAST5Algorithm));
mUseOldMethod = (algorithm == kPGPdiskOldCAST5Algorithm);
#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
CCast5Cipher::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(S1, sizeof(S1) / sizeof(PGPUInt32));
crc.Continue(S2, sizeof(S2) / sizeof(PGPUInt32));
crc.Continue(S3, sizeof(S3) / sizeof(PGPUInt32));
crc.Continue(S4, sizeof(S4) / sizeof(PGPUInt32));
crc.Continue(S5, sizeof(S5) / sizeof(PGPUInt32));
crc.Continue(S6, sizeof(S6) / sizeof(PGPUInt32));
crc.Continue(S7, sizeof(S7) / sizeof(PGPUInt32));
crc.Continue(S8, sizeof(S8) / 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
CCast5Cipher::AttachKey(
const Crypto::SymmetricKey& key,
const Crypto::PassphraseSalt& salt)
{
mKeyInfo1.Wipe();
mKeyInfo2.Wipe();
mKeyInfo1->key = key;
mKeyInfo1->salt = salt;
// Expand the key for non-CFB purposes.
CAST5Schedule(mKeyInfo1->expandedKey.dwords, mKeyInfo1->key.bytes);
// Initialize the expanded key using the old method if asked.
if (mUseOldMethod)
{
pgpClearMemory(mKeyInfo1->expandedKeyCFB.bytes,
sizeof(mKeyInfo1->expandedKeyCFB.bytes));
pgpCopyMemory(mKeyInfo1->key.bytes,
mKeyInfo1->expandedKeyCFB.bytes, NumKeyBytes());
#if USE_CAST5_ASSEMBLY
for (PGPUInt32 i = 0; i < 32; i += 2)
{
mKeyInfo1->expandedKeyCFB.dwords[i + 1] =
mKeyInfo1->expandedKeyCFB.dwords[i + 1] ^ 16;
}
#endif // !USE_CAST5_ASSEMBLY
}
else
{
mKeyInfo1->expandedKeyCFB = mKeyInfo1->expandedKey;
}
// Setup key 2.
*mKeyInfo2 = *mKeyInfo1;
mKeyInfo2.FlipBytes();
mTrueIfUsingKey1 = TRUE;
mPCurKeyInfo = mKeyInfo1.Get();
mIsKeyAttached = TRUE;
}
void
CCast5Cipher::FlipKeyBytes()
{
pgpAssert(IsKeyAttached());
mKeyInfo1.FlipBytes();
mKeyInfo2.FlipBytes();
if (mTrueIfUsingKey1)
{
mPCurKeyInfo = mKeyInfo2.Get();
mTrueIfUsingKey1 = FALSE;
}
else
{
mPCurKeyInfo = mKeyInfo1.Get();
mTrueIfUsingKey1 = TRUE;
}
}
void
CCast5Cipher::Encrypt(const void *in, void *out, PGPUInt32 numBlocks) const
{
pgpAssert(IsKeyAttached());
pgpAssertAddrValid(in, VoidAlign);
pgpAssertAddrValid(out, VoidAlign);
PGPByte *dataIn = static_cast<PGPByte *>(const_cast<void *>(in));
PGPByte *dataOut = static_cast<PGPByte *>(out);
for (PGPUInt32 i = 0; i < numBlocks; i++)
{
CAST5Encrypt(dataIn + (i*NumEncryptBytes()),
dataOut + (i*NumEncryptBytes()),
mPCurKeyInfo->expandedKey.dwords);
}
}
void
CCast5Cipher::Decrypt(const void *in, void *out, PGPUInt32 numBlocks) const
{
pgpAssert(IsKeyAttached());
pgpAssertAddrValid(in, VoidAlign);
pgpAssertAddrValid(out, VoidAlign);
PGPByte *dataIn = static_cast<PGPUInt8 *>(const_cast<void *>(in));
PGPByte *dataOut = static_cast<PGPUInt8 *>(out);
for (PGPUInt32 i = 0; i < numBlocks; i++)
{
CAST5Decrypt(dataIn + (i*NumDecryptBytes()),
dataOut + (i*NumDecryptBytes()),
mPCurKeyInfo->expandedKey.dwords);
}
}
void
CCast5Cipher::EncryptCFBdbl(
PGPUInt32 ivs[],
const PGPUInt32* src,
PGPUInt32* dest,
PGPUInt32 len) const
{
pgpAssert(IsKeyAttached());
pgpAssertAddrValid(src, PGPUIn32);
pgpAssertAddrValid(dest, PGPUIn32);
CAST5EncryptCFBdbl(mPCurKeyInfo->expandedKeyCFB.dwords, ivs[0], ivs[1],
ivs[2], ivs[3], src, dest, len);
}
void
CCast5Cipher::DecryptCFBdbl(
PGPUInt32 ivs[],
const PGPUInt32* src,
PGPUInt32* dest,
PGPUInt32 len) const
{
pgpAssert(IsKeyAttached());
pgpAssertAddrValid(src, PGPUIn32);
pgpAssertAddrValid(dest, PGPUIn32);
CAST5DecryptCFBdbl(mPCurKeyInfo->expandedKeyCFB.dwords, ivs[0], ivs[1],
ivs[2], ivs[3], src, dest, len);
}
SMART_ERROR
CCast5Cipher::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
CCast5Cipher::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 + -