📄 unativecryptomodule.cpp
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: UNativeCryptoModule.cpp,v 1.11 2002/08/06 20:10:19 dallen Exp $
____________________________________________________________________________*/
#include "pgpClassesConfig.h"
#include "CSecureObject.h"
#include "UMath.h"
#include "UString.h"
#include "UTime.h"
#include "CCast5Cipher.h"
#include "CCipher.h"
#include "CSHA.h"
#include "CTwofishCipher.h"
#include "UCommonStrings.h"
#include "UNativeCryptoModule.h"
#include "pgpClientErrors.h"
_USING_PGP
_UNNAMED_BEGIN
// Constants
enum
{
kBlockSizeIn32 = Crypto::kCipherBlockSize / sizeof(PGPUInt32),
kMaxHashReps = 16000,
kMaxMsTimeForHash = 500
};
// Macros
#define EXTRACT_CIPHER(keyHandle) \
CCipher *pCipher = static_cast<CCipher *>(keyHandle); \
pgpAssertAddrValid(pCipher, CCipher);
// Class CCipherWrapper
class CCipherWrapper SMART_ERROR_INHERIT
{
public:
CCipherWrapper(CCipher *pCipher) : mPCipher(pCipher)
{
pgpAssertAddrValid(pCipher, CCipher);
}
CCipherWrapper(PGPdiskEncryptionAlgorithm algorithm) :
mWeCreated(FALSE), mPCipher(NULL)
{
#if PGP_EXCEPTIONS
Make(algorithm);
mWeCreated = TRUE;
#else // !PGP_EXCEPTIONS
Status() = Make(algorithm);
if (Status().IsntError())
mWeCreated = TRUE;
#endif // PGP_EXCEPTIONS
}
~CCipherWrapper()
{
if (WeCreated())
{
delete mPCipher;
mPCipher = NULL;
}
}
operator CCipher *() {return mPCipher;}
operator const CCipher *() const {return mPCipher;}
CCipher * operator->() {return mPCipher;}
const CCipher * operator->() const {return mPCipher;}
CCipher& operator*() {return *mPCipher;}
const CCipher& operator*() const {return *mPCipher;}
CCipher * Get() {return mPCipher;}
PGPBoolean WeCreated() const {return mWeCreated;}
CCipher * Release()
{
CCipher *pCipher = mPCipher;
mWeCreated = FALSE;
mPCipher = NULL;
return pCipher;
}
private:
PGPBoolean mWeCreated;
CCipher *mPCipher;
SMART_ERROR Make(PGPdiskEncryptionAlgorithm algorithm);
};
// Function declarations
void GetAlgorithmIdString(PGPdiskEncryptionAlgorithm algorithm,
char *idString, PGPUInt32 availSize);
PGPUInt32 GetEncryptSize(Crypto::KeyHandle keyHandle);
PGPUInt32 GetDecryptSize(Crypto::KeyHandle keyHandle);
PGPUInt32 GetKeySize(Crypto::KeyHandle keyHandle);
PGPUInt32 GetNeededRandomDataSize(Crypto::KeyHandle keyHandle);
PGPUInt32 GetSizeForExport(Crypto::KeyHandle keyHandle);
CComboError Validate(Crypto::KeyHandle keyHandle);
CComboError Init(Crypto::KeyHandle *pKeyHandle,
PGPdiskEncryptionAlgorithm algorithm);
void Cleanup(Crypto::KeyHandle keyHandle);
CComboError AttachSymmetricKey(Crypto::KeyHandle keyHandle,
const Crypto::SymmetricKey *pKey,
const Crypto::PassphraseSalt *pSalt);
CComboError GetSymmetricKey(Crypto::KeyHandle keyHandle,
Crypto::SymmetricKey *pKey);
CComboError GetSalt(Crypto::KeyHandle keyHandle,
Crypto::PassphraseSalt *pSalt);
CComboError FlipKeyBytes(Crypto::KeyHandle keyHandle);
CComboError Encrypt(Crypto::KeyHandle keyHandle, const void *in,
void *out, PGPUInt32 numBlocks = 1);
CComboError Decrypt(Crypto::KeyHandle keyHandle, const void *in,
void *out, PGPUInt32 numBlocks = 1);
CComboError EncryptCFB(Crypto::KeyHandle keyHandle,
PGPUInt64 startBlockIndex, PGPUInt32 numBlocks,
const void *inBlocks, void *outBlocks);
CComboError DecryptCFB(Crypto::KeyHandle keyHandle,
PGPUInt64 startBlockIndex, PGPUInt32 numBlocks,
const void *inBlocks, void *outBlocks);
CComboError EncryptPassphraseKey(Crypto::KeyHandle keyHandle,
const char *passphrase, Crypto::PassphraseKeyInfo *pKeyInfo);
CComboError DecryptPassphraseKey(Crypto::KeyHandle keyHandle,
const char *passphrase, const Crypto::PassphraseSalt *pSalt,
const Crypto::PassphraseKeyInfo *pKeyInfo);
CComboError GenerateNewSymmetricKey(Crypto::KeyHandle keyHandle,
PGPUInt8 *randomData1, PGPUInt8 *randomData2, PGPUInt32 bytesData,
const Crypto::PassphraseSalt *pSalt);
CComboError Export(Crypto::KeyHandle keyHandle, void *buffer,
PGPUInt32 sizeBuffer);
CComboError Import(Crypto::KeyHandle keyHandle, const void *buffer,
PGPUInt32 sizeBuffer);
void EncryptBlock(const CCipher *pCipher, PGPUInt64 blockNumber,
const PGPUInt32 *inBlock, PGPUInt32 *outBlock);
void DecryptBlock(const CCipher *pCipher, PGPUInt64 blockNumber,
const PGPUInt32 *inBlock, PGPUInt32 *outBlock);
SMART_ERROR HashSaltSchedulePassphrase(const char *passphrase,
const Crypto::PassphraseSalt *pSalt, CCipher *pCipher,
PGPUInt16& hashReps, PGPBoolean generateNewHashReps);
// Class CCipherWrapper member functions
SMART_ERROR
CCipherWrapper::Make(PGPdiskEncryptionAlgorithm algorithm)
{
pgpAssert(!mWeCreated);
SMART_ERROR_DECLARE
if ((algorithm == kPGPdiskOldCAST5Algorithm) ||
(algorithm == kPGPdiskCAST5Algorithm))
{
mPCipher = new CCast5Cipher(algorithm);
}
else if (algorithm == kPGPdiskTwoFishAlgorithm)
{
mPCipher = new CTwofishCipher(algorithm);
}
else
{
#if PGP_EXCEPTIONS
THROW_PGPERROR(kPGPError_BadParams);
#else // !PGP_EXCEPTIONS
error.pgpErr = kPGPError_BadParams;
#endif // PGP_EXCEPTIONS
}
#if !PGP_EXCEPTIONS
if (error.IsntError())
{
if (IsNull(mPCipher))
error.pgpErr = kPGPError_OutOfMemory;
}
if (error.IsntError())
{
error = mPCipher->Status();
if (error.IsError())
{
delete mPCipher;
mPCipher = NULL;
}
}
#endif // !PGP_EXCEPTIONS
SMART_ERROR_RETURN
}
// Local function definitions.
void
GetAlgorithmIdString(
PGPdiskEncryptionAlgorithm algorithm,
char *idString,
PGPUInt32 availSize)
{
using namespace UCommonStrings;
pgpAssertAddrValid(idString, char);
switch (algorithm)
{
case kPGPdiskCAST5Algorithm:
UString::SmartStringCopy(idString, Get(kAlgorithmCast5IDString),
availSize);
break;
case kPGPdiskOldCAST5Algorithm:
UString::SmartStringCopy(idString, Get(kAlgorithmOldCast5IDString),
availSize);
break;
case kPGPdiskTwoFishAlgorithm:
UString::SmartStringCopy(idString, Get(kAlgorithmTwoFishIDString),
availSize);
break;
default:
pgpAssert(FALSE);
idString[0] = '\0';
break;
}
}
PGPUInt32
GetEncryptSize(Crypto::KeyHandle keyHandle)
{
EXTRACT_CIPHER(keyHandle)
return pCipher->NumEncryptBytes();
}
PGPUInt32
GetDecryptSize(Crypto::KeyHandle keyHandle)
{
EXTRACT_CIPHER(keyHandle)
return pCipher->NumDecryptBytes();
}
PGPUInt32
GetKeySize(Crypto::KeyHandle keyHandle)
{
EXTRACT_CIPHER(keyHandle)
return pCipher->NumKeyBytes();
}
PGPUInt32
GetNeededRandomDataSize(Crypto::KeyHandle keyHandle)
{
EXTRACT_CIPHER(keyHandle)
return pCipher->NumKeyBytes();
}
PGPUInt32
GetSizeForExport(Crypto::KeyHandle keyHandle)
{
EXTRACT_CIPHER(keyHandle)
return pCipher->SizeExportedCipher();
}
CComboError
Validate(Crypto::KeyHandle keyHandle)
{
CComboError error;
EXTRACT_CIPHER(keyHandle)
#if PGP_EXCEPTIONS
try
{
pCipher->Validate();
}
catch (CComboError& caughtErr)
{
error = caughtErr;
}
#else // !PGP_EXCEPTIONS
error = pCipher->Validate();
#endif // PGP_EXCEPTIONS
return error;
}
CComboError
Init(
Crypto::KeyHandle *pKeyHandle,
PGPdiskEncryptionAlgorithm algorithm)
{
CComboError error;
CCipher **ppCipher = reinterpret_cast<CCipher **>(pKeyHandle);
pgpAssertAddrValid(ppCipher, CCipher *);
#if PGP_EXCEPTIONS
try
{
CCipherWrapper pCipher(algorithm);
*ppCipher = pCipher.Release();
}
catch (CComboError& caughtErr)
{
error = caughtErr;
}
#else // !PGP_EXCEPTIONS
CCipherWrapper pCipher(algorithm);
error = pCipher.Status();
if (error.IsntError())
*ppCipher = pCipher.Release();
#endif // PGP_EXCEPTIONS
return error;
}
void
Cleanup(Crypto::KeyHandle keyHandle)
{
EXTRACT_CIPHER(keyHandle)
delete pCipher;
}
CComboError
AttachSymmetricKey(
Crypto::KeyHandle keyHandle,
const Crypto::SymmetricKey *pKey,
const Crypto::PassphraseSalt *pSalt)
{
CComboError error;
EXTRACT_CIPHER(keyHandle)
pgpAssertAddrValid(pKey, Crypto::SymmetricKey);
pgpAssertAddrValid(pSalt, Crypto::PassphraseSalt);
pCipher->AttachKey(*pKey, *pSalt);
return error;
}
CComboError
GetSymmetricKey(Crypto::KeyHandle keyHandle, Crypto::SymmetricKey *pKey)
{
pgpAssertAddrValid(pKey, Crypto::SymmetricKey);
CComboError error;
EXTRACT_CIPHER(keyHandle)
*pKey = pCipher->Key();
return error;
}
CComboError
GetSalt(Crypto::KeyHandle keyHandle, Crypto::PassphraseSalt *pSalt)
{
pgpAssertAddrValid(pSalt, Crypto::PassphraseSalt);
CComboError error;
EXTRACT_CIPHER(keyHandle)
*pSalt = pCipher->Salt();
return error;
}
CComboError
FlipKeyBytes(Crypto::KeyHandle keyHandle)
{
CComboError error;
EXTRACT_CIPHER(keyHandle)
pCipher->FlipKeyBytes();
return error;
}
CComboError
Encrypt(
Crypto::KeyHandle keyHandle,
const void *in,
void *out,
PGPUInt32 numBlocks)
{
pgpAssertAddrValid(in, VoidAlign);
pgpAssertAddrValid(out, VoidAlign);
CComboError error;
EXTRACT_CIPHER(keyHandle)
pCipher->Encrypt(in, out, numBlocks);
return error;
}
CComboError
Decrypt(
Crypto::KeyHandle keyHandle,
const void *in,
void *out,
PGPUInt32 numBlocks)
{
pgpAssertAddrValid(in, VoidAlign);
pgpAssertAddrValid(out, VoidAlign);
CComboError error;
EXTRACT_CIPHER(keyHandle)
pCipher->Decrypt(in, out, numBlocks);
return error;
}
CComboError
EncryptCFB(
Crypto::KeyHandle keyHandle,
PGPUInt64 startBlockIndex,
PGPUInt32 numBlocks,
const void *inBlocks,
void *outBlocks)
{
pgpAssertAddrValid(inBlocks, VoidAlign);
pgpAssertAddrValid(outBlocks, VoidAlign);
CComboError error;
EXTRACT_CIPHER(keyHandle)
const PGPUInt8 *curInBlock = static_cast<const PGPUInt8 *>(inBlocks);
PGPUInt8 *curOutBlock = static_cast<PGPUInt8 *>(outBlocks);
for (PGPUInt32 blockIndex = 0; blockIndex < numBlocks; blockIndex++)
{
PGPUInt64 seedValue = startBlockIndex + blockIndex;
EncryptBlock(pCipher, seedValue,
reinterpret_cast<const PGPUInt32 *>(curInBlock),
reinterpret_cast<PGPUInt32 *>(curOutBlock));
curInBlock += Crypto::kCipherBlockSize;
curOutBlock += Crypto::kCipherBlockSize;
}
return error;
}
CComboError
DecryptCFB(
Crypto::KeyHandle keyHandle,
PGPUInt64 startBlockIndex,
PGPUInt32 numBlocks,
const void *inBlocks,
void *outBlocks)
{
pgpAssertAddrValid(inBlocks, VoidAlign);
pgpAssertAddrValid(outBlocks, VoidAlign);
CComboError error;
EXTRACT_CIPHER(keyHandle)
const PGPUInt8 *curInBlock = static_cast<const PGPUInt8 *>(inBlocks);
PGPUInt8 *curOutBlock = static_cast<PGPUInt8 *>(outBlocks);
for (PGPUInt32 blockIndex = 0; blockIndex < numBlocks; blockIndex++)
{
PGPUInt64 seedValue = startBlockIndex + blockIndex;
DecryptBlock(pCipher, seedValue,
reinterpret_cast<const PGPUInt32 *>(curInBlock),
reinterpret_cast<PGPUInt32 *>(curOutBlock));
curInBlock += Crypto::kCipherBlockSize;
curOutBlock += Crypto::kCipherBlockSize;
}
return error;
}
CComboError
EncryptPassphraseKey(
Crypto::KeyHandle keyHandle,
const char *passphrase,
Crypto::PassphraseKeyInfo *pKeyInfo)
{
pgpAssertStrValid(passphrase);
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
{
pgpClearMemory(pKeyInfo, sizeof(Crypto::PassphraseKeyInfo));
#if PGP_EXCEPTIONS
HashSaltSchedulePassphrase(passphrase, &pCipher->Salt(),
pPassCipher, pKeyInfo->hashReps, TRUE);
#else // !PGP_EXCEPTIONS
error = HashSaltSchedulePassphrase(passphrase, &pCipher->Salt(),
pPassCipher, pKeyInfo->hashReps, TRUE);
#endif // PGP_EXCEPTIONS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -