added support for using encoding parameters and key derivation parameters

This commit is contained in:
weidai 2003-07-16 01:53:45 +00:00
parent 8cd6a9256d
commit 38b49e4543
29 changed files with 409 additions and 399 deletions

View File

@ -262,4 +262,6 @@ History
- fixed a number of compiler warnings, minor bugs, and portability problems
- removed Sapphire
5.2 - Merged in changes for 5.01 - 5.04
5.2 - Merged in changes for 5.01 - 5.0.4
- added support for using encoding parameters and key derivation parameters
with public key encryption (implemented by OAEP and DLIES)

View File

@ -10,6 +10,33 @@ NAMESPACE_BEGIN(CryptoPP)
bool (*AssignIntToInteger)(const std::type_info &valueType, void *pInteger, const void *pInt) = NULL;
bool CombinedNameValuePairs::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
{
if (strcmp(name, "ValueNames") == 0)
return m_pairs1.GetVoidValue(name, valueType, pValue) && m_pairs2.GetVoidValue(name, valueType, pValue);
else
return m_pairs1.GetVoidValue(name, valueType, pValue) || m_pairs2.GetVoidValue(name, valueType, pValue);
}
bool AlgorithmParametersBase::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
{
if (strcmp(name, "ValueNames") == 0)
{
ThrowIfTypeMismatch(name, typeid(std::string), valueType);
GetParent().GetVoidValue(name, valueType, pValue);
(*reinterpret_cast<std::string *>(pValue) += m_name) += ";";
return true;
}
else if (strcmp(name, m_name) == 0)
{
AssignValue(name, valueType, pValue);
m_used = true;
return true;
}
else
return GetParent().GetVoidValue(name, valueType, pValue);
}
NAMESPACE_END
#endif

View File

@ -73,14 +73,9 @@ public:
CombinedNameValuePairs(const NameValuePairs &pairs1, const NameValuePairs &pairs2)
: m_pairs1(pairs1), m_pairs2(pairs2) {}
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
{
if (strcmp(name, "ValueNames") == 0)
return m_pairs1.GetVoidValue(name, valueType, pValue) && m_pairs2.GetVoidValue(name, valueType, pValue);
else
return m_pairs1.GetVoidValue(name, valueType, pValue) || m_pairs2.GetVoidValue(name, valueType, pValue);
}
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
private:
const NameValuePairs &m_pairs1, &m_pairs2;
};
@ -247,73 +242,100 @@ CRYPTOPP_DLL extern bool (*AssignIntToInteger)(const std::type_info &valueType,
CRYPTOPP_DLL const std::type_info & IntegerTypeId();
template <class BASE, class T>
class AlgorithmParameters : public NameValuePairs
class CRYPTOPP_DLL AlgorithmParametersBase : public NameValuePairs
{
public:
AlgorithmParameters(const BASE &base, const char *name, const T &value)
: m_base(base), m_name(name), m_value(value)
#ifndef NDEBUG
, m_used(false)
class ParameterNotUsed : public Exception
{
public:
ParameterNotUsed(const char *name) : Exception(OTHER_ERROR, std::string("AlgorithmParametersBase: parameter \"") + name + "\" not used") {}
};
AlgorithmParametersBase(const char *name, bool throwIfNotUsed)
: m_name(name), m_throwIfNotUsed(throwIfNotUsed), m_used(false) {}
~AlgorithmParametersBase()
{
#ifdef CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE
if (!std::uncaught_exception())
#else
try
#endif
{
if (m_throwIfNotUsed && !m_used)
throw ParameterNotUsed(m_name);
}
#ifndef CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE
catch(...)
{
}
#endif
}
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
protected:
virtual void AssignValue(const char *name, const std::type_info &valueType, void *pValue) const =0;
virtual const NameValuePairs & GetParent() const =0;
bool m_throwIfNotUsed;
mutable bool m_used;
const char *m_name;
};
template <class T>
class AlgorithmParametersBase2 : public AlgorithmParametersBase
{
public:
AlgorithmParametersBase2(const char *name, const T &value, bool throwIfNotUsed) : AlgorithmParametersBase(name, throwIfNotUsed), m_value(value) {}
void AssignValue(const char *name, const std::type_info &valueType, void *pValue) const
{
// special case for retrieving an Integer parameter when an int was passed in
if (!(AssignIntToInteger != NULL && typeid(T) == typeid(int) && AssignIntToInteger(valueType, pValue, &m_value)))
{
ThrowIfTypeMismatch(name, typeid(T), valueType);
*reinterpret_cast<T *>(pValue) = m_value;
}
}
protected:
T m_value;
};
template <class PARENT, class T>
class AlgorithmParameters : public AlgorithmParametersBase2<T>
{
public:
AlgorithmParameters(const PARENT &parent, const char *name, const T &value, bool throwIfNotUsed)
: AlgorithmParametersBase2<T>(name, value, throwIfNotUsed), m_parent(parent)
{}
#ifndef NDEBUG
AlgorithmParameters(const AlgorithmParameters &copy)
: m_base(copy.m_base), m_name(copy.m_name), m_value(copy.m_value), m_used(false)
: AlgorithmParametersBase2<T>(copy), m_parent(copy.m_parent)
{
copy.m_used = true;
}
// TODO: revisit after implementing some tracing mechanism, this won't work because of exceptions
// ~AlgorithmParameters() {assert(m_used);} // use assert here because we don't want to throw out of a destructor
#endif
template <class R>
AlgorithmParameters<AlgorithmParameters<BASE,T>, R> operator()(const char *name, const R &value) const
AlgorithmParameters<AlgorithmParameters<PARENT,T>, R> operator()(const char *name, const R &value) const
{
return AlgorithmParameters<AlgorithmParameters<BASE,T>, R>(*this, name, value);
}
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
{
if (strcmp(name, "ValueNames") == 0)
{
ThrowIfTypeMismatch(name, typeid(std::string), valueType);
m_base.GetVoidValue(name, valueType, pValue);
(*reinterpret_cast<std::string *>(pValue) += m_name) += ";";
return true;
}
else if (strcmp(name, m_name) == 0)
{
// special case for retrieving an Integer parameter when an int was passed in
if (!(AssignIntToInteger != NULL && typeid(T) == typeid(int) && AssignIntToInteger(valueType, pValue, &m_value)))
{
ThrowIfTypeMismatch(name, typeid(T), valueType);
*reinterpret_cast<T *>(pValue) = m_value;
}
#ifndef NDEBUG
m_used = true;
#endif
return true;
}
else
return m_base.GetVoidValue(name, valueType, pValue);
return AlgorithmParameters<AlgorithmParameters<PARENT,T>, R>(*this, name, value, m_throwIfNotUsed);
}
private:
BASE m_base;
const char *m_name;
T m_value;
#ifndef NDEBUG
mutable bool m_used;
#endif
const NameValuePairs & GetParent() const {return m_parent;}
PARENT m_parent;
};
//! Create an object that implements NameValuePairs for passing parameters
/*! \param throwIfNotUsed if true, the object will throw an exception if the value is not accessed
\note throwIfNotUsed is ignored if using a compiler that does not support std::uncaught_exception(),
such as MSVC 7.0 and earlier. */
template <class T>
AlgorithmParameters<NullNameValuePairs,T> MakeParameters(const char *name, const T &value)
AlgorithmParameters<NullNameValuePairs,T> MakeParameters(const char *name, const T &value, bool throwIfNotUsed = true)
{
return AlgorithmParameters<NullNameValuePairs,T>(g_nullNameValuePairs, name, value);
return AlgorithmParameters<NullNameValuePairs,T>(g_nullNameValuePairs, name, value, throwIfNotUsed);
}
#define CRYPTOPP_GET_FUNCTION_ENTRY(name) (Name::name(), &ThisClass::Get##name)

View File

@ -33,6 +33,7 @@ CRYPTOPP_DEFINE_NAME_STRING(Cofactor) //!< Integer
CRYPTOPP_DEFINE_NAME_STRING(SubgroupGenerator) //!< Integer, ECP::Point, or EC2N::Point
CRYPTOPP_DEFINE_NAME_STRING(Curve) //!< ECP or EC2N
CRYPTOPP_DEFINE_NAME_STRING(GroupOID) //!< OID
CRYPTOPP_DEFINE_NAME_STRING(PointerToPrimeSelector) //!< const PrimeSelector *
CRYPTOPP_DEFINE_NAME_STRING(Prime1) //!< Integer
CRYPTOPP_DEFINE_NAME_STRING(Prime2) //!< Integer
CRYPTOPP_DEFINE_NAME_STRING(ModPrime1PrivateExponent) //!< Integer
@ -52,6 +53,8 @@ CRYPTOPP_DEFINE_NAME_STRING(InputBinaryMode) //!< bool
CRYPTOPP_DEFINE_NAME_STRING(OutputFileName) //!< const char *
CRYPTOPP_DEFINE_NAME_STRING(OutputStreamPointer) //!< std::ostream *
CRYPTOPP_DEFINE_NAME_STRING(OutputBinaryMode) //!< bool
CRYPTOPP_DEFINE_NAME_STRING(EncodingParameters) //!< ConstByteArrayParameter
CRYPTOPP_DEFINE_NAME_STRING(KeyDerivationParameters) //!< ConstByteArrayParameter
DOCUMENTED_NAMESPACE_END

View File

@ -193,6 +193,8 @@ void Grouper::IsolatedInitialize(const NameValuePairs &parameters)
ConstByteArrayParameter separator, terminator;
if (m_groupSize)
parameters.GetRequiredParameter("Grouper", "Separator", separator);
else
parameters.GetValue("Separator", separator);
parameters.GetValue("Terminator", terminator);
m_separator.Assign(separator.begin(), separator.size());

View File

@ -167,21 +167,11 @@ WasBlocked:
return 0;
}
void ChannelSwitch::ChannelInitialize(const std::string &channel, const NameValuePairs &parameters/* =g_nullNameValuePairs */, int propagation/* =-1 */)
void ChannelSwitch::IsolatedInitialize(const NameValuePairs &parameters/* =g_nullNameValuePairs */)
{
if (channel.empty())
{
m_routeMap.clear();
m_defaultRoutes.clear();
}
m_it.Reset(channel);
while (!m_it.End())
{
m_it.Destination().ChannelInitialize(m_it.Channel(), parameters, propagation);
m_it.Next();
}
m_routeMap.clear();
m_defaultRoutes.clear();
m_blocked = false;
}
bool ChannelSwitch::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking)

View File

@ -90,10 +90,11 @@ public:
AddDefaultRoute(destination, outChannel);
}
void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs);
unsigned int ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking);
unsigned int ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking);
void ChannelInitialize(const std::string &channel, const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true);
bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true);

View File

@ -191,6 +191,10 @@ NAMESPACE_END
# pragma warning(disable: 4231 4250 4251 4275 4660 4661 4786 4355)
#endif
#if !(defined(_MSC_VER) && _MSC_VER <= 1300)
#define CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE
#endif
// ***************** determine availability of OS features ********************
#ifndef NO_OS_DEPENDENCE

View File

@ -53,7 +53,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 advapi32.lib /nologo /base:"0x69000000" /dll /debug /machine:I386 /out:"DLL_Release/cryptopp.dll" /opt:ref /export:CryptoPP_Malloc=malloc /export:CryptoPP_Free=free
# ADD LINK32 advapi32.lib /nologo /base:"0x42900000" /dll /debug /machine:I386 /out:"DLL_Release/cryptopp.dll" /opt:ref /export:CryptoPP_Malloc=malloc /export:CryptoPP_Free=free
# SUBTRACT LINK32 /pdb:none
# Begin Custom Build
OutDir=.\DLL_Release
@ -91,7 +91,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 advapi32.lib /nologo /base:"0x69000000" /dll /incremental:no /debug /machine:I386 /out:"DLL_Debug/cryptopp.dll" /opt:ref
# ADD LINK32 advapi32.lib /nologo /base:"0x42900000" /dll /incremental:no /debug /machine:I386 /out:"DLL_Debug/cryptopp.dll" /opt:ref
# SUBTRACT LINK32 /pdb:none
# Begin Custom Build
OutDir=.\DLL_Debug

View File

@ -10,6 +10,7 @@
#include "algparam.h"
#include "fips140.h"
#include "argnames.h"
#include "fltrimpl.h"
#include <memory>
@ -224,14 +225,6 @@ unsigned int BufferedTransformation::ChannelPutModifiable2(const std::string &ch
return ChannelPut2(channel, begin, length, messageEnd, blocking);
}
void BufferedTransformation::ChannelInitialize(const std::string &channel, const NameValuePairs &parameters, int propagation)
{
if (channel.empty())
Initialize(parameters, propagation);
else
throw NoChannelSupport();
}
bool BufferedTransformation::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking)
{
if (channel.empty())
@ -527,100 +520,89 @@ void GeneratableCryptoMaterial::GenerateRandomWithKeySize(RandomNumberGenerator
GenerateRandom(rng, MakeParameters("KeySize", (int)keySize));
}
BufferedTransformation * PK_Encryptor::CreateEncryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment) const
BufferedTransformation * PK_Encryptor::CreateEncryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment, const NameValuePairs &parameters) const
{
struct EncryptionFilter : public Unflushable<FilterWithInputQueue>
struct EncryptionFilter : public Unflushable<Filter>
{
// VC60 complains if this function is missing
EncryptionFilter(const EncryptionFilter &x) : Unflushable<FilterWithInputQueue>(NULL), m_rng(x.m_rng), m_encryptor(x.m_encryptor) {}
EncryptionFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment)
: Unflushable<FilterWithInputQueue>(attachment), m_rng(rng), m_encryptor(encryptor)
EncryptionFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment, const NameValuePairs &parameters)
: Unflushable<Filter>(attachment), m_rng(rng), m_encryptor(encryptor), m_parameters(parameters)
{
}
bool IsolatedMessageEnd(bool blocking)
unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
{
switch (m_continueAt)
FILTER_BEGIN;
m_plaintextQueue.Put(inString, length);
if (messageEnd)
{
case 0:
{
unsigned int plaintextLength = m_inQueue.CurrentSize();
m_ciphertextLength = m_encryptor.CiphertextLength(plaintextLength);
unsigned int plaintextLength = m_plaintextQueue.CurrentSize();
unsigned int ciphertextLength = m_encryptor.CiphertextLength(plaintextLength);
SecByteBlock plaintext(plaintextLength);
m_inQueue.Get(plaintext, plaintextLength);
m_ciphertext.resize(m_ciphertextLength);
m_encryptor.Encrypt(m_rng, plaintext, plaintextLength, m_ciphertext);
m_plaintextQueue.Get(plaintext, plaintextLength);
m_ciphertext.resize(ciphertextLength);
m_encryptor.Encrypt(m_rng, plaintext, plaintextLength, m_ciphertext, m_parameters);
}
case 1:
if (!Output(1, m_ciphertext, m_ciphertextLength, 0, blocking))
return false;
};
return true;
FILTER_OUTPUT(1, m_ciphertext, m_ciphertext.size(), messageEnd);
}
FILTER_END_NO_MESSAGE_END;
}
RandomNumberGenerator &m_rng;
const PK_Encryptor &m_encryptor;
unsigned int m_ciphertextLength;
const NameValuePairs &m_parameters;
ByteQueue m_plaintextQueue;
SecByteBlock m_ciphertext;
};
return new EncryptionFilter(rng, *this, attachment);
return new EncryptionFilter(rng, *this, attachment, parameters);
}
BufferedTransformation * PK_Decryptor::CreateDecryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment) const
BufferedTransformation * PK_Decryptor::CreateDecryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment, const NameValuePairs &parameters) const
{
struct DecryptionFilter : public Unflushable<FilterWithInputQueue>
struct DecryptionFilter : public Unflushable<Filter>
{
// VC60 complains if this function is missing
DecryptionFilter(const DecryptionFilter &x) : Unflushable<FilterWithInputQueue>(NULL), m_rng(x.m_rng), m_decryptor(x.m_decryptor) {}
DecryptionFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment)
: Unflushable<FilterWithInputQueue>(attachment), m_rng(rng), m_decryptor(decryptor)
DecryptionFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment, const NameValuePairs &parameters)
: Unflushable<Filter>(attachment), m_rng(rng), m_decryptor(decryptor), m_parameters(parameters)
{
}
bool IsolatedMessageEnd(bool blocking)
unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
{
switch (m_continueAt)
FILTER_BEGIN;
m_ciphertextQueue.Put(inString, length);
if (messageEnd)
{
case 0:
{
unsigned int ciphertextLength = m_inQueue.CurrentSize();
unsigned int ciphertextLength = m_ciphertextQueue.CurrentSize();
unsigned int maxPlaintextLength = m_decryptor.MaxPlaintextLength(ciphertextLength);
SecByteBlock ciphertext(ciphertextLength);
m_inQueue.Get(ciphertext, ciphertextLength);
m_ciphertextQueue.Get(ciphertext, ciphertextLength);
m_plaintext.resize(maxPlaintextLength);
m_result = m_decryptor.Decrypt(m_rng, ciphertext, ciphertextLength, m_plaintext);
m_result = m_decryptor.Decrypt(m_rng, ciphertext, ciphertextLength, m_plaintext, m_parameters);
if (!m_result.isValidCoding)
throw InvalidCiphertext(m_decryptor.AlgorithmName() + ": invalid ciphertext");
}
case 1:
if (!Output(1, m_plaintext, m_result.messageLength, 0, blocking))
return false;
FILTER_OUTPUT(1, m_plaintext, m_result.messageLength, messageEnd);
}
return true;
FILTER_END_NO_MESSAGE_END;
}
RandomNumberGenerator &m_rng;
const PK_Decryptor &m_decryptor;
const NameValuePairs &m_parameters;
ByteQueue m_ciphertextQueue;
SecByteBlock m_plaintext;
DecodingResult m_result;
};
return new DecryptionFilter(rng, *this, attachment);
}
DecodingResult PK_FixedLengthDecryptor::Decrypt(RandomNumberGenerator &rng, const byte *cipherText, unsigned int cipherTextLength, byte *plainText) const
{
if (cipherTextLength != FixedCiphertextLength())
return DecodingResult();
return FixedLengthDecrypt(rng, cipherText, plainText);
return new DecryptionFilter(rng, *this, attachment, parameters);
}
unsigned int PK_Signer::Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const

View File

@ -220,7 +220,7 @@ public:
virtual ~NameValuePairs() {}
//! exception thrown when trying to retrieve a value using a different type than expected
class ValueTypeMismatch : public InvalidArgument
class CRYPTOPP_DLL ValueTypeMismatch : public InvalidArgument
{
public:
ValueTypeMismatch(std::string name, const std::type_info &stored, const std::type_info &retrieving)
@ -913,7 +913,6 @@ public:
virtual unsigned int ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking);
virtual unsigned int ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking);
virtual void ChannelInitialize(const std::string &channel, const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
virtual bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true);
virtual bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true);
@ -1117,6 +1116,18 @@ public:
/*! \note This function returns 0 if plaintextLength is not valid (too long). */
virtual unsigned int CiphertextLength(unsigned int plaintextLength) const =0;
//! this object supports the use of the parameter with the given name
/*! some possible parameter names: EncodingParameters, KeyDerivationParameters */
virtual bool ParameterSupported(const char *name) const =0;
//! return fixed ciphertext length, if one exists, otherwise return 0
/*! \note "Fixed" here means length of ciphertext does not depend on length of plaintext.
It usually does depend on the key length. */
virtual unsigned int FixedCiphertextLength() const {return 0;}
//! return maximum plaintext length given the fixed ciphertext length, if one exists, otherwise return 0
virtual unsigned int FixedMaxPlaintextLength() const {return 0;}
#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
unsigned int MaxPlainTextLength(unsigned int cipherTextLength) const {return MaxPlaintextLength(cipherTextLength);}
unsigned int CipherTextLength(unsigned int plainTextLength) const {return CiphertextLength(plainTextLength);}
@ -1124,7 +1135,6 @@ public:
};
//! interface for public-key encryptors
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Encryptor : virtual public PK_CryptoSystem, public PublicKeyAlgorithm
{
public:
@ -1139,12 +1149,16 @@ public:
/*! \pre CiphertextLength(plaintextLength) != 0 (i.e., plaintext isn't too long)
\pre size of ciphertext == CiphertextLength(plaintextLength)
*/
virtual void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, unsigned int plaintextLength, byte *ciphertext) const =0;
virtual void Encrypt(RandomNumberGenerator &rng,
const byte *plaintext, unsigned int plaintextLength,
byte *ciphertext, const NameValuePairs &parameters = g_nullNameValuePairs) const =0;
//! create a new encryption filter
/*! \note caller is responsible for deleting the returned pointer
/*! \note The caller is responsible for deleting the returned pointer.
\note Encoding parameters should be passed in the "EP" channel.
*/
virtual BufferedTransformation * CreateEncryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment=NULL) const;
virtual BufferedTransformation * CreateEncryptionFilter(RandomNumberGenerator &rng,
BufferedTransformation *attachment=NULL, const NameValuePairs &parameters = g_nullNameValuePairs) const;
};
//! interface for public-key decryptors
@ -1154,67 +1168,28 @@ class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Decryptor : virtual public PK_CryptoSys
public:
//! decrypt a byte string, and return the length of plaintext
/*! \pre size of plaintext == MaxPlaintextLength(ciphertextLength) bytes.
\return the actual length of the plaintext, or 0 if decryption fails.
\return the actual length of the plaintext, indication that decryption failed.
*/
virtual DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, unsigned int ciphertextLength, byte *plaintext) const =0;
virtual DecodingResult Decrypt(RandomNumberGenerator &rng,
const byte *ciphertext, unsigned int ciphertextLength,
byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const =0;
//! create a new decryption filter
/*! \note caller is responsible for deleting the returned pointer
*/
virtual BufferedTransformation * CreateDecryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment=NULL) const;
virtual BufferedTransformation * CreateDecryptionFilter(RandomNumberGenerator &rng,
BufferedTransformation *attachment=NULL, const NameValuePairs &parameters = g_nullNameValuePairs) const;
//! decrypt a fixed size ciphertext
DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *ciphertext, byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const
{return Decrypt(rng, ciphertext, FixedCiphertextLength(), plaintext, parameters);}
};
//! interface for encryptors and decryptors with fixed length ciphertext
/*! A simplified interface is provided for crypto systems (such
as RSA) whose ciphertext length and maximum plaintext length
depend only on the key.
*/
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystem
{
public:
//!
virtual unsigned int FixedMaxPlaintextLength() const =0;
//!
virtual unsigned int FixedCiphertextLength() const =0;
#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
unsigned int MaxPlainTextLength(unsigned int cipherTextLength) const {return MaxPlaintextLength(cipherTextLength);}
unsigned int CipherTextLength(unsigned int plainTextLength) const {return CiphertextLength(plainTextLength);}
unsigned int MaxPlainTextLength() const {return FixedMaxPlaintextLength();}
unsigned int CipherTextLength() const {return FixedCiphertextLength();}
typedef PK_CryptoSystem PK_FixedLengthCryptoSystem;
typedef PK_Encryptor PK_FixedLengthEncryptor;
typedef PK_Decryptor PK_FixedLengthDecryptor;
#endif
};
template <class BASE>
class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystemImpl : public BASE, public PK_FixedLengthCryptoSystem
{
unsigned int MaxPlaintextLength(unsigned int ciphertextLength) const
{return ciphertextLength == FixedCiphertextLength() ? FixedMaxPlaintextLength() : 0;}
unsigned int CiphertextLength(unsigned int plaintextLength) const
{return plaintextLength <= FixedMaxPlaintextLength() ? FixedCiphertextLength() : 0;}
};
//! interface for encryptors with fixed length ciphertext
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_FixedLengthEncryptor : public PK_FixedLengthCryptoSystemImpl<PK_Encryptor>
{
};
//! interface for decryptors with fixed length ciphertext
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_FixedLengthDecryptor : public PK_FixedLengthCryptoSystemImpl<PK_Decryptor>
{
public:
//! decrypt a byte string, and return the length of plaintext
/*! \pre length of ciphertext == FixedCiphertextLength()
\pre size of plaintext == FixedMaxPlaintextLength()
\return the actual length of the plaintext, or 0 if decryption fails.
*/
virtual DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *ciphertext, byte *plaintext) const =0;
DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, unsigned int ciphertextLength, byte *plaintext) const;
};
//! interface for public-key signers and verifiers

View File

@ -15,7 +15,6 @@
#include "algebra.cpp"
#include "eprecomp.cpp"
#include "eccrypto.cpp"
#include "oaep.cpp"
#ifndef CRYPTOPP_IMPORTS

View File

@ -11,7 +11,7 @@ class CRYPTOPP_NO_VTABLE ElGamalBase : public DL_KeyAgreementAlgorithm_DH<Intege
public DL_SymmetricEncryptionAlgorithm
{
public:
void Derive(const DL_GroupParameters<Integer> &params, byte *derivedKey, unsigned int derivedLength, const Integer &agreedElement, const Integer &ephemeralPublicKey) const
void Derive(const DL_GroupParameters<Integer> &groupParams, byte *derivedKey, unsigned int derivedLength, const Integer &agreedElement, const Integer &ephemeralPublicKey, const NameValuePairs &derivationParams) const
{
agreedElement.Encode(derivedKey, derivedLength);
}
@ -39,7 +39,7 @@ public:
return 0;
}
void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plainText, unsigned int plainTextLength, byte *cipherText) const
void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plainText, unsigned int plainTextLength, byte *cipherText, const NameValuePairs &parameters) const
{
const Integer &p = GetGroupParameters().GetModulus();
unsigned int modulusLen = p.ByteCount();
@ -52,7 +52,7 @@ public:
a_times_b_mod_c(Integer(key, modulusLen), Integer(block, modulusLen-1), p).Encode(cipherText, modulusLen);
}
DecodingResult SymmetricDecrypt(const byte *key, const byte *cipherText, unsigned int cipherTextLength, byte *plainText) const
DecodingResult SymmetricDecrypt(const byte *key, const byte *cipherText, unsigned int cipherTextLength, byte *plainText, const NameValuePairs &parameters) const
{
const Integer &p = GetGroupParameters().GetModulus();
unsigned int modulusLen = p.ByteCount();
@ -106,14 +106,14 @@ struct ElGamal
static const char * StaticAlgorithmName() {return "ElgamalEnc/Crypto++Padding";}
class CRYPTOPP_NO_VTABLE EncryptorImpl : public ElGamalObjectImpl<DL_EncryptorBase<Integer, PK_FixedLengthEncryptor>, SchemeOptions, SchemeOptions::PublicKey>, public PublicKeyCopier<SchemeOptions>
class CRYPTOPP_NO_VTABLE EncryptorImpl : public ElGamalObjectImpl<DL_EncryptorBase<Integer>, SchemeOptions, SchemeOptions::PublicKey>, public PublicKeyCopier<SchemeOptions>
{
public:
void CopyKeyInto(SchemeOptions::PublicKey &key) const
{key = GetKey();}
};
class CRYPTOPP_NO_VTABLE DecryptorImpl : public ElGamalObjectImpl<DL_DecryptorBase<Integer, PK_FixedLengthDecryptor>, SchemeOptions, SchemeOptions::PrivateKey>, public PrivateKeyCopier<SchemeOptions>
class CRYPTOPP_NO_VTABLE DecryptorImpl : public ElGamalObjectImpl<DL_DecryptorBase<Integer>, SchemeOptions, SchemeOptions::PrivateKey>, public PrivateKeyCopier<SchemeOptions>
{
public:
void CopyKeyInto(SchemeOptions::PublicKey &key) const

View File

@ -95,10 +95,10 @@ bool Filter::MessageSeriesEnd(int propagation, bool blocking)
return false;
}
void Filter::PropagateInitialize(const NameValuePairs &parameters, int propagation, const std::string &channel)
void Filter::PropagateInitialize(const NameValuePairs &parameters, int propagation)
{
if (propagation)
AttachedTransformation()->ChannelInitialize(channel, parameters, propagation-1);
AttachedTransformation()->Initialize(parameters, propagation-1);
}
unsigned int Filter::OutputModifiable(int outputSite, byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string &channel)
@ -409,16 +409,13 @@ void FilterWithBufferedInput::NextPutMultiple(const byte *inString, unsigned int
// *************************************************************
void Redirector::ChannelInitialize(const std::string &channel, const NameValuePairs &parameters, int propagation)
void Redirector::Initialize(const NameValuePairs &parameters, int propagation)
{
if (channel.empty())
{
m_target = parameters.GetValueWithDefault("RedirectionTargetPointer", (BufferedTransformation*)NULL);
m_behavior = parameters.GetIntValueWithDefault("RedirectionBehavior", PASS_EVERYTHING);
}
m_target = parameters.GetValueWithDefault("RedirectionTargetPointer", (BufferedTransformation*)NULL);
m_behavior = parameters.GetIntValueWithDefault("RedirectionBehavior", PASS_EVERYTHING);
if (m_target && GetPassSignals())
m_target->ChannelInitialize(channel, parameters, propagation);
m_target->Initialize(parameters, propagation);
}
// *************************************************************

View File

@ -36,7 +36,7 @@ protected:
virtual bool ShouldPropagateMessageEnd() const {return true;}
virtual bool ShouldPropagateMessageSeriesEnd() const {return true;}
void PropagateInitialize(const NameValuePairs &parameters, int propagation, const std::string &channel=NULL_CHANNEL);
void PropagateInitialize(const NameValuePairs &parameters, int propagation);
unsigned int Output(int outputSite, const byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string &channel=NULL_CHANNEL);
unsigned int OutputModifiable(int outputSite, byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string &channel=NULL_CHANNEL);
@ -395,8 +395,7 @@ public:
bool CanModifyInput() const
{return m_target ? m_target->CanModifyInput() : false;}
void Initialize(const NameValuePairs &parameters, int propagation)
{ChannelInitialize(NULL_CHANNEL, parameters, propagation);}
void Initialize(const NameValuePairs &parameters, int propagation);
byte * CreatePutSpace(unsigned int &size)
{return m_target ? m_target->CreatePutSpace(size) : (byte *)(size=0, NULL);}
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
@ -406,7 +405,6 @@ public:
bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
{return m_target && GetPassSignals() ? m_target->MessageSeriesEnd(propagation, blocking) : false;}
void ChannelInitialize(const std::string &channel, const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
byte * ChannelCreatePutSpace(const std::string &channel, unsigned int &size)
{return m_target ? m_target->ChannelCreatePutSpace(channel, size) : (byte *)(size=0, NULL);}
unsigned int ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking)
@ -454,8 +452,6 @@ public:
{return m_owner.AttachedTransformation()->ChannelPut2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);}
unsigned int ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking)
{return m_owner.AttachedTransformation()->ChannelPutModifiable2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);}
void ChannelInitialize(const std::string &channel, const NameValuePairs &parameters, int propagation=-1)
{if (m_passSignal) m_owner.AttachedTransformation()->ChannelInitialize(channel, parameters, propagation);}
bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true)
{return m_passSignal ? m_owner.AttachedTransformation()->ChannelFlush(channel, completeFlush, propagation, blocking) : false;}
bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true)

View File

@ -418,13 +418,14 @@ template <class MAC, bool DHAES_MODE>
class DL_EncryptionAlgorithm_Xor : public DL_SymmetricEncryptionAlgorithm
{
public:
unsigned int GetSymmetricKeyLength(unsigned int plainTextLength) const
{return plainTextLength + MAC::DEFAULT_KEYLENGTH;}
unsigned int GetSymmetricCiphertextLength(unsigned int plainTextLength) const
{return plainTextLength + MAC::DIGESTSIZE;}
unsigned int GetMaxSymmetricPlaintextLength(unsigned int cipherTextLength) const
{return SaturatingSubtract(cipherTextLength, (unsigned int)MAC::DIGESTSIZE);}
void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plainText, unsigned int plainTextLength, byte *cipherText) const
bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;}
unsigned int GetSymmetricKeyLength(unsigned int plaintextLength) const
{return plaintextLength + MAC::DEFAULT_KEYLENGTH;}
unsigned int GetSymmetricCiphertextLength(unsigned int plaintextLength) const
{return plaintextLength + MAC::DIGESTSIZE;}
unsigned int GetMaxSymmetricPlaintextLength(unsigned int ciphertextLength) const
{return SaturatingSubtract(ciphertextLength, (unsigned int)MAC::DIGESTSIZE);}
void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, unsigned int plaintextLength, byte *ciphertext, const NameValuePairs &parameters) const
{
const byte *cipherKey, *macKey;
if (DHAES_MODE)
@ -435,22 +436,27 @@ public:
else
{
cipherKey = key;
macKey = key + plainTextLength;
macKey = key + plaintextLength;
}
xorbuf(cipherText, plainText, cipherKey, plainTextLength);
ConstByteArrayParameter encodingParameters;
parameters.GetValue(Name::EncodingParameters(), encodingParameters);
xorbuf(ciphertext, plaintext, cipherKey, plaintextLength);
MAC mac(macKey);
mac.Update(cipherText, plainTextLength);
mac.Update(ciphertext, plaintextLength);
mac.Update(encodingParameters.begin(), encodingParameters.size());
if (DHAES_MODE)
{
const byte L[8] = {0,0,0,0,0,0,0,0};
byte L[8] = {0,0,0,0};
UnalignedPutWord(BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size()));
mac.Update(L, 8);
}
mac.Final(cipherText + plainTextLength);
mac.Final(ciphertext + plaintextLength);
}
DecodingResult SymmetricDecrypt(const byte *key, const byte *cipherText, unsigned int cipherTextLength, byte *plainText) const
DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, unsigned int ciphertextLength, byte *plaintext, const NameValuePairs &parameters) const
{
unsigned int plainTextLength = GetMaxSymmetricPlaintextLength(cipherTextLength);
unsigned int plaintextLength = GetMaxSymmetricPlaintextLength(ciphertextLength);
const byte *cipherKey, *macKey;
if (DHAES_MODE)
{
@ -460,21 +466,26 @@ public:
else
{
cipherKey = key;
macKey = key + plainTextLength;
macKey = key + plaintextLength;
}
ConstByteArrayParameter encodingParameters;
parameters.GetValue(Name::EncodingParameters(), encodingParameters);
MAC mac(macKey);
mac.Update(cipherText, plainTextLength);
mac.Update(ciphertext, plaintextLength);
mac.Update(encodingParameters.begin(), encodingParameters.size());
if (DHAES_MODE)
{
const byte L[8] = {0,0,0,0,0,0,0,0};
byte L[8] = {0,0,0,0};
UnalignedPutWord(BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size()));
mac.Update(L, 8);
}
if (!mac.Verify(cipherText + plainTextLength))
if (!mac.Verify(ciphertext + plaintextLength))
return DecodingResult();
xorbuf(plainText, cipherText, cipherKey, plainTextLength);
return DecodingResult(plainTextLength);
xorbuf(plaintext, ciphertext, cipherKey, plaintextLength);
return DecodingResult(plaintextLength);
}
};
@ -483,7 +494,8 @@ template <class T, bool DHAES_MODE, class KDF>
class DL_KeyDerivationAlgorithm_P1363 : public DL_KeyDerivationAlgorithm<T>
{
public:
void Derive(const DL_GroupParameters<T> &params, byte *derivedKey, unsigned int derivedLength, const T &agreedElement, const T &ephemeralPublicKey) const
bool ParameterSupported(const char *name) const {return strcmp(name, Name::KeyDerivationParameters()) == 0;}
void Derive(const DL_GroupParameters<T> &params, byte *derivedKey, unsigned int derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &parameters) const
{
SecByteBlock agreedSecret;
if (DHAES_MODE)
@ -498,7 +510,9 @@ public:
params.EncodeElement(false, agreedElement, agreedSecret);
}
KDF::DeriveKey(derivedKey, derivedLength, agreedSecret, agreedSecret.size());
ConstByteArrayParameter derivationParameters;
parameters.GetValue(Name::KeyDerivationParameters(), derivationParameters);
KDF::DeriveKey(derivedKey, derivedLength, agreedSecret, agreedSecret.size(), derivationParameters.begin(), derivationParameters.size());
}
};

25
ida.cpp
View File

@ -17,11 +17,8 @@ using namespace std;
NAMESPACE_BEGIN(CryptoPP)
void RawIDA::ChannelInitialize(const string &channel, const NameValuePairs &parameters, int propagation)
void RawIDA::IsolatedInitialize(const NameValuePairs &parameters)
{
if (!channel.empty())
throw NotImplemented("RawIDA: can't reinitialize a channel");
if (!parameters.GetIntValue("RecoveryThreshold", m_threshold))
throw InvalidArgument("RawIDA: missing RecoveryThreshold argument");
@ -48,10 +45,6 @@ void RawIDA::ChannelInitialize(const string &channel, const NameValuePairs &para
for (int i=0; i<nShares; i++)
AddOutputChannel(i);
}
if (propagation)
for (unsigned int i=0; i<m_outputChannelIds.size(); i++)
AttachedTransformation()->ChannelInitialize(m_outputChannelIdStrings[i], parameters, propagation-1);
}
unsigned int RawIDA::InsertInputChannel(word32 channelId)
@ -240,10 +233,10 @@ void RawIDA::OutputMessageEnds()
// ****************************************************************
void SecretSharing::Initialize(const NameValuePairs &parameters, int propagation)
void SecretSharing::IsolatedInitialize(const NameValuePairs &parameters)
{
m_pad = parameters.GetValueWithDefault("AddPadding", true);
m_ida.Initialize(parameters, propagation);
m_ida.IsolatedInitialize(parameters);
}
unsigned int SecretSharing::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
@ -283,10 +276,10 @@ unsigned int SecretSharing::Put2(const byte *begin, unsigned int length, int mes
return 0;
}
void SecretRecovery::Initialize(const NameValuePairs &parameters, int propagation)
void SecretRecovery::IsolatedInitialize(const NameValuePairs &parameters)
{
m_pad = parameters.GetValueWithDefault("RemovePadding", true);
RawIDA::Initialize(CombinedNameValuePairs(parameters, MakeParameters("OutputChannelID", (word32)0xffffffff)), propagation);
RawIDA::IsolatedInitialize(CombinedNameValuePairs(parameters, MakeParameters("OutputChannelID", (word32)0xffffffff)));
}
void SecretRecovery::FlushOutputQueues()
@ -311,11 +304,11 @@ void SecretRecovery::OutputMessageEnds()
// ****************************************************************
void InformationDispersal::Initialize(const NameValuePairs &parameters, int propagation)
void InformationDispersal::IsolatedInitialize(const NameValuePairs &parameters)
{
m_nextChannel = 0;
m_pad = parameters.GetValueWithDefault("AddPadding", true);
m_ida.Initialize(parameters, propagation);
m_ida.IsolatedInitialize(parameters);
}
unsigned int InformationDispersal::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
@ -344,10 +337,10 @@ unsigned int InformationDispersal::Put2(const byte *begin, unsigned int length,
return 0;
}
void InformationRecovery::Initialize(const NameValuePairs &parameters, int propagation)
void InformationRecovery::IsolatedInitialize(const NameValuePairs &parameters)
{
m_pad = parameters.GetValueWithDefault("RemovePadding", true);
RawIDA::Initialize(parameters, propagation);
RawIDA::IsolatedInitialize(parameters);
}
void InformationRecovery::FlushOutputQueues()

26
ida.h
View File

@ -21,7 +21,7 @@ public:
void ChannelData(word32 channelId, const byte *inString, unsigned int length, bool messageEnd);
unsigned int InputBuffered(word32 channelId) const;
void ChannelInitialize(const std::string &channel, const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs);
unsigned int ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking)
{
if (!blocking)
@ -53,14 +53,14 @@ protected:
};
/// a variant of Shamir's Secret Sharing Algorithm
class SecretSharing : public CustomSignalPropagation<Filter>
class SecretSharing : public CustomFlushPropagation<Filter>
{
public:
SecretSharing(RandomNumberGenerator &rng, int threshold, int nShares, BufferedTransformation *attachment=NULL, bool addPadding=true)
: CustomSignalPropagation<Filter>(attachment), m_rng(rng), m_ida(new OutputProxy(*this, true))
{Initialize(MakeParameters("RecoveryThreshold", threshold)("NumberOfShares", nShares)("AddPadding", addPadding), 0);}
: CustomFlushPropagation<Filter>(attachment), m_rng(rng), m_ida(new OutputProxy(*this, true))
{IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("NumberOfShares", nShares)("AddPadding", addPadding));}
void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs);
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) {return m_ida.Flush(hardFlush, propagation, blocking);}
@ -76,9 +76,9 @@ class SecretRecovery : public RawIDA
public:
SecretRecovery(int threshold, BufferedTransformation *attachment=NULL, bool removePadding=true)
: RawIDA(attachment)
{Initialize(MakeParameters("RecoveryThreshold", threshold)("RemovePadding", removePadding), 0);}
{IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("RemovePadding", removePadding));}
void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs);
protected:
void FlushOutputQueues();
@ -88,14 +88,14 @@ protected:
};
/// a variant of Rabin's Information Dispersal Algorithm
class InformationDispersal : public CustomSignalPropagation<Filter>
class InformationDispersal : public CustomFlushPropagation<Filter>
{
public:
InformationDispersal(int threshold, int nShares, BufferedTransformation *attachment=NULL, bool addPadding=true)
: CustomSignalPropagation<Filter>(attachment), m_ida(new OutputProxy(*this, true))
{Initialize(MakeParameters("RecoveryThreshold", threshold)("NumberOfShares", nShares)("AddPadding", addPadding), 0);}
: CustomFlushPropagation<Filter>(attachment), m_ida(new OutputProxy(*this, true))
{IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("NumberOfShares", nShares)("AddPadding", addPadding));}
void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs);
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) {return m_ida.Flush(hardFlush, propagation, blocking);}
@ -111,9 +111,9 @@ class InformationRecovery : public RawIDA
public:
InformationRecovery(int threshold, BufferedTransformation *attachment=NULL, bool removePadding=true)
: RawIDA(attachment)
{Initialize(MakeParameters("RecoveryThreshold", threshold)("RemovePadding", removePadding), 0);}
{IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("RemovePadding", removePadding));}
void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs);
protected:
void FlushOutputQueues();

View File

@ -3026,7 +3026,7 @@ public:
{
UnalignedPutWord(BIG_ENDIAN_ORDER, m_counterAndSeed, m_counter);
++m_counter;
P1363_KDF2<SHA1>::DeriveKey(output, size, m_counterAndSeed, m_counterAndSeed.size());
P1363_KDF2<SHA1>::DeriveKey(output, size, m_counterAndSeed, m_counterAndSeed.size(), NULL, 0);
}
private:
@ -3095,7 +3095,7 @@ bool Integer::GenerateRandomNoThrow(RandomNumberGenerator &i_rng, const NameValu
case PRIME:
{
const PrimeSelector *pSelector = params.GetValueWithDefault("PointerToPrimeSelector", (const PrimeSelector *)NULL);
const PrimeSelector *pSelector = params.GetValueWithDefault(Name::PointerToPrimeSelector(), (const PrimeSelector *)NULL);
int i;
i = 0;

View File

@ -132,19 +132,6 @@ mismatch:
}
}
void EqualityComparisonFilter::ChannelInitialize(const std::string &channel, const NameValuePairs &parameters, int propagation)
{
unsigned int i = MapChannel(channel);
if (i == 2)
PropagateInitialize(parameters, propagation, channel);
else
{
m_q[i].Initialize();
m_mismatchDetected = false;
}
}
bool EqualityComparisonFilter::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking)
{
unsigned int i = MapChannel(channel);

View File

@ -73,8 +73,6 @@ public:
, m_firstChannel(firstChannel), m_secondChannel(secondChannel) {}
unsigned int ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking);
void ChannelInitialize(const std::string &channel, const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true);
private:

View File

@ -9,30 +9,12 @@ NAMESPACE_BEGIN(CryptoPP)
// ********************************************************
ANONYMOUS_NAMESPACE_BEGIN
template <class H, byte *P, unsigned int PLen>
struct PHashComputation
{
PHashComputation() {H().CalculateDigest(pHash, P, PLen);}
byte pHash[H::DIGESTSIZE];
};
template <class H, byte *P, unsigned int PLen>
const byte *PHash()
{
static PHashComputation<H,P,PLen> pHash;
return pHash.pHash;
}
NAMESPACE_END
template <class H, class MGF, byte *P, unsigned int PLen>
unsigned int OAEP<H,MGF,P,PLen>::MaxUnpaddedLength(unsigned int paddedLength) const
unsigned int OAEP_Base::MaxUnpaddedLength(unsigned int paddedLength) const
{
return paddedLength/8 > 1+2*H::DIGESTSIZE ? paddedLength/8-1-2*H::DIGESTSIZE : 0;
return SaturatingSubtract(paddedLength/8, 1+2*DigestSize());
}
template <class H, class MGF, byte *P, unsigned int PLen>
void OAEP<H,MGF,P,PLen>::Pad(RandomNumberGenerator &rng, const byte *input, unsigned int inputLength, byte *oaepBlock, unsigned int oaepBlockLen) const
void OAEP_Base::Pad(RandomNumberGenerator &rng, const byte *input, unsigned int inputLength, byte *oaepBlock, unsigned int oaepBlockLen, const NameValuePairs &parameters) const
{
assert (inputLength <= MaxUnpaddedLength(oaepBlockLen));
@ -44,26 +26,28 @@ void OAEP<H,MGF,P,PLen>::Pad(RandomNumberGenerator &rng, const byte *input, unsi
}
oaepBlockLen /= 8;
const unsigned int hLen = H::DIGESTSIZE;
std::auto_ptr<HashTransformation> pHash(NewHash());
const unsigned int hLen = pHash->DigestSize();
const unsigned int seedLen = hLen, dbLen = oaepBlockLen-seedLen;
byte *const maskedSeed = oaepBlock;
byte *const maskedDB = oaepBlock+seedLen;
ConstByteArrayParameter encodingParameters;
parameters.GetValue(Name::EncodingParameters(), encodingParameters);
// DB = pHash || 00 ... || 01 || M
memcpy(maskedDB, PHash<H,P,PLen>(), hLen);
pHash->CalculateDigest(maskedDB, encodingParameters.begin(), encodingParameters.size());
memset(maskedDB+hLen, 0, dbLen-hLen-inputLength-1);
maskedDB[dbLen-inputLength-1] = 0x01;
memcpy(maskedDB+dbLen-inputLength, input, inputLength);
rng.GenerateBlock(maskedSeed, seedLen);
H h;
MGF mgf;
mgf.GenerateAndMask(h, maskedDB, dbLen, maskedSeed, seedLen);
mgf.GenerateAndMask(h, maskedSeed, seedLen, maskedDB, dbLen);
std::auto_ptr<MaskGeneratingFunction> pMGF(NewMGF());
pMGF->GenerateAndMask(*pHash, maskedDB, dbLen, maskedSeed, seedLen);
pMGF->GenerateAndMask(*pHash, maskedSeed, seedLen, maskedDB, dbLen);
}
template <class H, class MGF, byte *P, unsigned int PLen>
DecodingResult OAEP<H,MGF,P,PLen>::Unpad(const byte *oaepBlock, unsigned int oaepBlockLen, byte *output) const
DecodingResult OAEP_Base::Unpad(const byte *oaepBlock, unsigned int oaepBlockLen, byte *output, const NameValuePairs &parameters) const
{
bool invalid = false;
@ -75,7 +59,8 @@ DecodingResult OAEP<H,MGF,P,PLen>::Unpad(const byte *oaepBlock, unsigned int oae
}
oaepBlockLen /= 8;
const unsigned int hLen = H::DIGESTSIZE;
std::auto_ptr<HashTransformation> pHash(NewHash());
const unsigned int hLen = pHash->DigestSize();
const unsigned int seedLen = hLen, dbLen = oaepBlockLen-seedLen;
invalid = (oaepBlockLen < 2*hLen+1) || invalid;
@ -84,17 +69,18 @@ DecodingResult OAEP<H,MGF,P,PLen>::Unpad(const byte *oaepBlock, unsigned int oae
byte *const maskedSeed = t;
byte *const maskedDB = t+seedLen;
H h;
MGF mgf;
mgf.GenerateAndMask(h, maskedSeed, seedLen, maskedDB, dbLen);
mgf.GenerateAndMask(h, maskedDB, dbLen, maskedSeed, seedLen);
std::auto_ptr<MaskGeneratingFunction> pMGF(NewMGF());
pMGF->GenerateAndMask(*pHash, maskedSeed, seedLen, maskedDB, dbLen);
pMGF->GenerateAndMask(*pHash, maskedDB, dbLen, maskedSeed, seedLen);
ConstByteArrayParameter encodingParameters;
parameters.GetValue(Name::EncodingParameters(), encodingParameters);
// DB = pHash' || 00 ... || 01 || M
byte *M = std::find(maskedDB+hLen, maskedDB+dbLen, 0x01);
invalid = (M == maskedDB+dbLen) || invalid;
invalid = (std::find_if(maskedDB+hLen, M, std::bind2nd(std::not_equal_to<byte>(), 0)) != M) || invalid;
invalid = (memcmp(maskedDB, PHash<H,P,PLen>(), hLen) != 0) || invalid;
invalid = !pHash->VerifyDigest(maskedDB, encodingParameters.begin(), encodingParameters.size()) || invalid;
if (invalid)
return DecodingResult();

29
oaep.h
View File

@ -6,19 +6,32 @@
NAMESPACE_BEGIN(CryptoPP)
extern byte OAEP_P_DEFAULT[]; // defined in misc.cpp
//! <a href="http://www.weidai.com/scan-mirror/ca.html#cem_OAEP-MGF1">EME-OAEP</a>, for use with RSAES
class CRYPTOPP_DLL OAEP_Base : public PK_EncryptionMessageEncodingMethod
{
public:
bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;}
unsigned int MaxUnpaddedLength(unsigned int paddedLength) const;
void Pad(RandomNumberGenerator &rng, const byte *raw, unsigned int inputLength, byte *padded, unsigned int paddedLength, const NameValuePairs &parameters) const;
DecodingResult Unpad(const byte *padded, unsigned int paddedLength, byte *raw, const NameValuePairs &parameters) const;
/// <a href="http://www.weidai.com/scan-mirror/ca.html#cem_OAEP-MGF1">EME-OAEP</a>, for use with RSAES
template <class H, class MGF=P1363_MGF1, byte *P=OAEP_P_DEFAULT, unsigned int PLen=0>
class OAEP : public PK_EncryptionMessageEncodingMethod, public EncryptionStandard
protected:
virtual unsigned int DigestSize() const =0;
virtual HashTransformation * NewHash() const =0;
virtual MaskGeneratingFunction * NewMGF() const =0;
};
template <class H, class MGF=P1363_MGF1>
class OAEP : public OAEP_Base, public EncryptionStandard
{
public:
static std::string StaticAlgorithmName() {return std::string("OAEP-") + MGF::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";}
typedef OAEP<H, MGF, P, PLen> EncryptionMessageEncodingMethod;
typedef OAEP<H, MGF> EncryptionMessageEncodingMethod;
unsigned int MaxUnpaddedLength(unsigned int paddedLength) const;
void Pad(RandomNumberGenerator &rng, const byte *raw, unsigned int inputLength, byte *padded, unsigned int paddedLength) const;
DecodingResult Unpad(const byte *padded, unsigned int paddedLength, byte *raw) const;
protected:
unsigned int DigestSize() const {return H::DIGESTSIZE;}
HashTransformation * NewHash() const {return new H;}
MaskGeneratingFunction * NewMGF() const {return new MGF;}
};
CRYPTOPP_DLL_TEMPLATE_CLASS OAEP<SHA>;

View File

@ -33,7 +33,7 @@ unsigned int PKCS_EncryptionPaddingScheme::MaxUnpaddedLength(unsigned int padded
return SaturatingSubtract(paddedLength/8, 10U);
}
void PKCS_EncryptionPaddingScheme::Pad(RandomNumberGenerator &rng, const byte *input, unsigned int inputLen, byte *pkcsBlock, unsigned int pkcsBlockLen) const
void PKCS_EncryptionPaddingScheme::Pad(RandomNumberGenerator &rng, const byte *input, unsigned int inputLen, byte *pkcsBlock, unsigned int pkcsBlockLen, const NameValuePairs &parameters) const
{
assert (inputLen <= MaxUnpaddedLength(pkcsBlockLen)); // this should be checked by caller
@ -55,7 +55,7 @@ void PKCS_EncryptionPaddingScheme::Pad(RandomNumberGenerator &rng, const byte *i
memcpy(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);
}
DecodingResult PKCS_EncryptionPaddingScheme::Unpad(const byte *pkcsBlock, unsigned int pkcsBlockLen, byte *output) const
DecodingResult PKCS_EncryptionPaddingScheme::Unpad(const byte *pkcsBlock, unsigned int pkcsBlockLen, byte *output, const NameValuePairs &parameters) const
{
bool invalid = false;
unsigned int maxOutputLen = MaxUnpaddedLength(pkcsBlockLen);

View File

@ -17,8 +17,8 @@ public:
static const char * StaticAlgorithmName() {return "EME-PKCS1-v1_5";}
unsigned int MaxUnpaddedLength(unsigned int paddedLength) const;
void Pad(RandomNumberGenerator &rng, const byte *raw, unsigned int inputLength, byte *padded, unsigned int paddedLength) const;
DecodingResult Unpad(const byte *padded, unsigned int paddedLength, byte *raw) const;
void Pad(RandomNumberGenerator &rng, const byte *raw, unsigned int inputLength, byte *padded, unsigned int paddedLength, const NameValuePairs &parameters) const;
DecodingResult Unpad(const byte *padded, unsigned int paddedLength, byte *raw, const NameValuePairs &parameters) const;
};
template <class H> class PKCS_DigestDecoration

View File

@ -8,7 +8,7 @@
NAMESPACE_BEGIN(CryptoPP)
void P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, bool mask, unsigned int counterStart)
void P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, const byte *derivationParams, unsigned int derivationParamsLength, bool mask, unsigned int counterStart)
{
ArraySink *sink;
HashFilter filter(hash, sink = mask ? new ArrayXorSink(output, outputLength) : new ArraySink(output, outputLength));
@ -17,6 +17,7 @@ void P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, unsigned int
{
filter.Put(input, inputLength);
filter.PutWord32(counter++);
filter.Put(derivationParams, derivationParamsLength);
filter.MessageEnd();
}
}
@ -102,24 +103,24 @@ DecodingResult TF_VerifierBase::RecoverAndRestart(byte *recoveredMessage, PK_Mes
return result;
}
DecodingResult TF_DecryptorBase::FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *cipherText, byte *plainText) const
DecodingResult TF_DecryptorBase::Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, unsigned int ciphertextLength, byte *plaintext, const NameValuePairs &parameters) const
{
SecByteBlock paddedBlock(PaddedBlockByteLength());
Integer x = GetTrapdoorFunctionInterface().CalculateInverse(rng, Integer(cipherText, FixedCiphertextLength()));
Integer x = GetTrapdoorFunctionInterface().CalculateInverse(rng, Integer(ciphertext, FixedCiphertextLength()));
if (x.ByteCount() > paddedBlock.size())
x = Integer::Zero(); // don't return false here to prevent timing attack
x.Encode(paddedBlock, paddedBlock.size());
return GetMessageEncodingInterface().Unpad(paddedBlock, PaddedBlockBitLength(), plainText);
return GetMessageEncodingInterface().Unpad(paddedBlock, PaddedBlockBitLength(), plaintext, parameters);
}
void TF_EncryptorBase::Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText) const
void TF_EncryptorBase::Encrypt(RandomNumberGenerator &rng, const byte *plaintext, unsigned int plaintextLength, byte *ciphertext, const NameValuePairs &parameters) const
{
if (plainTextLength > FixedMaxPlaintextLength())
if (plaintextLength > FixedMaxPlaintextLength())
throw InvalidArgument(AlgorithmName() + ": message too long for this public key");
SecByteBlock paddedBlock(PaddedBlockByteLength());
GetMessageEncodingInterface().Pad(rng, plainText, plainTextLength, paddedBlock, PaddedBlockBitLength());
GetTrapdoorFunctionInterface().ApplyRandomizedFunction(rng, Integer(paddedBlock, paddedBlock.size())).Encode(cipherText, FixedCiphertextLength());
GetMessageEncodingInterface().Pad(rng, plaintext, plaintextLength, paddedBlock, PaddedBlockBitLength(), parameters);
GetTrapdoorFunctionInterface().ApplyRandomizedFunction(rng, Integer(paddedBlock, paddedBlock.size())).Encode(ciphertext, FixedCiphertextLength());
}
NAMESPACE_END

112
pubkey.h
View File

@ -100,18 +100,20 @@ public:
// ********************************************************
//! .
//! message encoding method for public key encryption
class CRYPTOPP_NO_VTABLE PK_EncryptionMessageEncodingMethod
{
public:
virtual ~PK_EncryptionMessageEncodingMethod() {}
virtual bool ParameterSupported(const char *name) const {return false;}
//! max size of unpadded message in bytes, given max size of padded message in bits (1 less than size of modulus)
virtual unsigned int MaxUnpaddedLength(unsigned int paddedLength) const =0;
virtual void Pad(RandomNumberGenerator &rng, const byte *raw, unsigned int inputLength, byte *padded, unsigned int paddedBitLength) const =0;
virtual void Pad(RandomNumberGenerator &rng, const byte *raw, unsigned int inputLength, byte *padded, unsigned int paddedBitLength, const NameValuePairs &parameters) const =0;
virtual DecodingResult Unpad(const byte *padded, unsigned int paddedBitLength, byte *raw) const =0;
virtual DecodingResult Unpad(const byte *padded, unsigned int paddedBitLength, byte *raw, const NameValuePairs &parameters) const =0;
};
// ********************************************************
@ -132,11 +134,25 @@ protected:
// ********************************************************
//! .
template <class INTERFACE, class BASE>
class CRYPTOPP_NO_VTABLE TF_CryptoSystemBase : public INTERFACE, protected BASE
template <class BASE>
class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystemImpl : public BASE
{
public:
unsigned int MaxPlaintextLength(unsigned int ciphertextLength) const
{return ciphertextLength == FixedCiphertextLength() ? FixedMaxPlaintextLength() : 0;}
unsigned int CiphertextLength(unsigned int plaintextLength) const
{return plaintextLength <= FixedMaxPlaintextLength() ? FixedCiphertextLength() : 0;}
virtual unsigned int FixedMaxPlaintextLength() const =0;
virtual unsigned int FixedCiphertextLength() const =0;
};
//! .
template <class INTERFACE, class BASE>
class CRYPTOPP_NO_VTABLE TF_CryptoSystemBase : public PK_FixedLengthCryptoSystemImpl<INTERFACE>, protected BASE
{
public:
bool ParameterSupported(const char *name) const {return GetMessageEncodingInterface().ParameterSupported(name);}
unsigned int FixedMaxPlaintextLength() const {return GetMessageEncodingInterface().MaxUnpaddedLength(PaddedBlockBitLength());}
unsigned int FixedCiphertextLength() const {return GetTrapdoorFunctionBounds().MaxImage().ByteCount();}
@ -146,17 +162,17 @@ protected:
};
//! .
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_DecryptorBase : public TF_CryptoSystemBase<PK_FixedLengthDecryptor, TF_Base<TrapdoorFunctionInverse, PK_EncryptionMessageEncodingMethod> >
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_DecryptorBase : public TF_CryptoSystemBase<PK_Decryptor, TF_Base<TrapdoorFunctionInverse, PK_EncryptionMessageEncodingMethod> >
{
public:
DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *cipherText, byte *plainText) const;
DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, unsigned int ciphertextLength, byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const;
};
//! .
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_EncryptorBase : public TF_CryptoSystemBase<PK_FixedLengthEncryptor, TF_Base<RandomizedTrapdoorFunction, PK_EncryptionMessageEncodingMethod> >
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_EncryptorBase : public TF_CryptoSystemBase<PK_Encryptor, TF_Base<RandomizedTrapdoorFunction, PK_EncryptionMessageEncodingMethod> >
{
public:
void Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText) const;
void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, unsigned int plaintextLength, byte *ciphertext, const NameValuePairs &parameters = g_nullNameValuePairs) const;
};
// ********************************************************
@ -482,25 +498,16 @@ public:
virtual void GenerateAndMask(HashTransformation &hash, byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, bool mask = true) const =0;
};
CRYPTOPP_DLL void P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, bool mask, unsigned int counterStart);
CRYPTOPP_DLL void P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, const byte *derivationParams, unsigned int derivationParamsLength, bool mask, unsigned int counterStart);
//! .
class P1363_MGF1 : public MaskGeneratingFunction
{
public:
static const char * StaticAlgorithmName() {return "MGF1";}
#if 0
// VC60 workaround: this function causes internal compiler error
template <class H>
static void GenerateAndMaskTemplate(byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, H* dummy=NULL)
{
H h;
P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, mask, 0);
}
#endif
void GenerateAndMask(HashTransformation &hash, byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, bool mask = true) const
{
P1363_MGF1KDF2_Common(hash, output, outputLength, input, inputLength, mask, 0);
P1363_MGF1KDF2_Common(hash, output, outputLength, input, inputLength, NULL, 0, mask, 0);
}
};
@ -511,10 +518,10 @@ template <class H>
class P1363_KDF2
{
public:
static void DeriveKey(byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength)
static void DeriveKey(byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength, const byte *derivationParams, unsigned int derivationParamsLength)
{
H h;
P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, false, 1);
P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, derivationParams, derivationParamsLength, false, 1);
}
};
@ -940,18 +947,20 @@ template <class T>
class CRYPTOPP_NO_VTABLE DL_KeyDerivationAlgorithm
{
public:
virtual void Derive(const DL_GroupParameters<T> &params, byte *derivedKey, unsigned int derivedLength, const T &agreedElement, const T &ephemeralPublicKey) const =0;
virtual bool ParameterSupported(const char *name) const {return false;}
virtual void Derive(const DL_GroupParameters<T> &groupParams, byte *derivedKey, unsigned int derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &derivationParams) const =0;
};
//! .
class CRYPTOPP_NO_VTABLE DL_SymmetricEncryptionAlgorithm
{
public:
virtual unsigned int GetSymmetricKeyLength(unsigned int plainTextLength) const =0;
virtual unsigned int GetSymmetricCiphertextLength(unsigned int plainTextLength) const =0;
virtual unsigned int GetMaxSymmetricPlaintextLength(unsigned int cipherTextLength) const =0;
virtual void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plainText, unsigned int plainTextLength, byte *cipherText) const =0;
virtual DecodingResult SymmetricDecrypt(const byte *key, const byte *cipherText, unsigned int cipherTextLength, byte *plainText) const =0;
virtual bool ParameterSupported(const char *name) const {return false;}
virtual unsigned int GetSymmetricKeyLength(unsigned int plaintextLength) const =0;
virtual unsigned int GetSymmetricCiphertextLength(unsigned int plaintextLength) const =0;
virtual unsigned int GetMaxSymmetricPlaintextLength(unsigned int ciphertextLength) const =0;
virtual void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, unsigned int plaintextLength, byte *ciphertext, const NameValuePairs &parameters) const =0;
virtual DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, unsigned int ciphertextLength, byte *plaintext, const NameValuePairs &parameters) const =0;
};
//! .
@ -1149,18 +1158,21 @@ class CRYPTOPP_NO_VTABLE DL_CryptoSystemBase : public PK, public DL_Base<KI>
public:
typedef typename DL_Base<KI>::Element Element;
unsigned int MaxPlaintextLength(unsigned int cipherTextLength) const
unsigned int MaxPlaintextLength(unsigned int ciphertextLength) const
{
unsigned int minLen = GetAbstractGroupParameters().GetEncodedElementSize(true);
return cipherTextLength < minLen ? 0 : GetSymmetricEncryptionAlgorithm().GetMaxSymmetricPlaintextLength(cipherTextLength - minLen);
return ciphertextLength < minLen ? 0 : GetSymmetricEncryptionAlgorithm().GetMaxSymmetricPlaintextLength(ciphertextLength - minLen);
}
unsigned int CiphertextLength(unsigned int plainTextLength) const
unsigned int CiphertextLength(unsigned int plaintextLength) const
{
unsigned int len = GetSymmetricEncryptionAlgorithm().GetSymmetricCiphertextLength(plainTextLength);
unsigned int len = GetSymmetricEncryptionAlgorithm().GetSymmetricCiphertextLength(plaintextLength);
return len == 0 ? 0 : GetAbstractGroupParameters().GetEncodedElementSize(true) + len;
}
bool ParameterSupported(const char *name) const
{return GetKeyDerivationAlgorithm().ParameterSupported(name) || GetSymmetricEncryptionAlgorithm().ParameterSupported(name);}
protected:
virtual const DL_KeyAgreementAlgorithm<Element> & GetKeyAgreementAlgorithm() const =0;
virtual const DL_KeyDerivationAlgorithm<Element> & GetKeyDerivationAlgorithm() const =0;
@ -1168,13 +1180,13 @@ protected:
};
//! .
template <class T, class PK = PK_Decryptor>
class CRYPTOPP_NO_VTABLE DL_DecryptorBase : public DL_CryptoSystemBase<PK, DL_PrivateKey<T> >
template <class T>
class CRYPTOPP_NO_VTABLE DL_DecryptorBase : public DL_CryptoSystemBase<PK_Decryptor, DL_PrivateKey<T> >
{
public:
typedef T Element;
DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *cipherText, unsigned int cipherTextLength, byte *plainText) const
DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, unsigned int ciphertextLength, byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const
{
try
{
@ -1184,17 +1196,17 @@ public:
const DL_GroupParameters<T> &params = GetAbstractGroupParameters();
const DL_PrivateKey<T> &key = GetKeyInterface();
Element q = params.DecodeElement(cipherText, true);
Element q = params.DecodeElement(ciphertext, true);
unsigned int elementSize = params.GetEncodedElementSize(true);
cipherText += elementSize;
cipherTextLength -= elementSize;
ciphertext += elementSize;
ciphertextLength -= elementSize;
Element z = agreeAlg.AgreeWithStaticPrivateKey(params, q, true, key.GetPrivateExponent());
SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(encAlg.GetMaxSymmetricPlaintextLength(cipherTextLength)));
derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q);
SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(encAlg.GetMaxSymmetricPlaintextLength(ciphertextLength)));
derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
return encAlg.SymmetricDecrypt(derivedKey, cipherText, cipherTextLength, plainText);
return encAlg.SymmetricDecrypt(derivedKey, ciphertext, ciphertextLength, plaintext, parameters);
}
catch (DL_BadElement &)
{
@ -1204,13 +1216,13 @@ public:
};
//! .
template <class T, class PK = PK_Encryptor>
class CRYPTOPP_NO_VTABLE DL_EncryptorBase : public DL_CryptoSystemBase<PK, DL_PublicKey<T> >
template <class T>
class CRYPTOPP_NO_VTABLE DL_EncryptorBase : public DL_CryptoSystemBase<PK_Encryptor, DL_PublicKey<T> >
{
public:
typedef T Element;
void Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText) const
void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, unsigned int plaintextLength, byte *ciphertext, const NameValuePairs &parameters = g_nullNameValuePairs) const
{
const DL_KeyAgreementAlgorithm<T> &agreeAlg = GetKeyAgreementAlgorithm();
const DL_KeyDerivationAlgorithm<T> &derivAlg = GetKeyDerivationAlgorithm();
@ -1220,16 +1232,16 @@ public:
Integer x(rng, Integer::One(), params.GetMaxExponent());
Element q = params.ExponentiateBase(x);
params.EncodeElement(true, q, cipherText);
params.EncodeElement(true, q, ciphertext);
unsigned int elementSize = params.GetEncodedElementSize(true);
cipherText += elementSize;
ciphertext += elementSize;
Element z = agreeAlg.AgreeWithEphemeralPrivateKey(params, key.GetPublicPrecomputation(), x);
SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(plainTextLength));
derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q);
SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(plaintextLength));
derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters);
encAlg.SymmetricEncrypt(rng, derivedKey, plainText, plainTextLength, cipherText);
encAlg.SymmetricEncrypt(rng, derivedKey, plaintext, plaintextLength, ciphertext, parameters);
}
};

10
rsa.cpp
View File

@ -16,8 +16,6 @@
NAMESPACE_BEGIN(CryptoPP)
byte OAEP_P_DEFAULT[1];
#if !defined(NDEBUG) && !defined(CRYPTOPP_IS_DLL)
void RSA_TestInstantiations()
{
@ -107,19 +105,19 @@ public:
void InvertibleRSAFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
{
int modulusSize = 2048;
alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize);
alg.GetIntValue(Name::ModulusSize(), modulusSize) || alg.GetIntValue(Name::KeySize(), modulusSize);
if (modulusSize < 16)
throw InvalidArgument("InvertibleRSAFunction: specified modulus size is too small");
m_e = alg.GetValueWithDefault("PublicExponent", Integer(17));
m_e = alg.GetValueWithDefault(Name::PublicExponent(), Integer(17));
if (m_e < 3 || m_e.IsEven())
throw InvalidArgument("InvertibleRSAFunction: invalid public exponent");
RSAPrimeSelector selector(m_e);
const NameValuePairs &primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize)
("PointerToPrimeSelector", selector.GetSelectorPointer());
(Name::PointerToPrimeSelector(), selector.GetSelectorPointer());
m_p.GenerateRandom(rng, primeParam);
m_q.GenerateRandom(rng, primeParam);
@ -145,7 +143,7 @@ void InvertibleRSAFunction::GenerateRandom(RandomNumberGenerator &rng, const Nam
void InvertibleRSAFunction::Initialize(RandomNumberGenerator &rng, unsigned int keybits, const Integer &e)
{
GenerateRandom(rng, MakeParameters("ModulusSize", (int)keybits)("PublicExponent", e+e.IsEven()));
GenerateRandom(rng, MakeParameters(Name::ModulusSize(), (int)keybits)(Name::PublicExponent(), e+e.IsEven()));
}
void InvertibleRSAFunction::Initialize(const Integer &n, const Integer &e, const Integer &d)

View File

@ -109,29 +109,38 @@ protected:
};
template <class T>
class CRYPTOPP_NO_VTABLE CustomSignalPropagation : public T
class CRYPTOPP_NO_VTABLE CustomFlushPropagation : public T
{
public:
CustomSignalPropagation() {}
CustomSignalPropagation(BufferedTransformation *q) : T(q) {}
CustomFlushPropagation() {}
CustomFlushPropagation(BufferedTransformation *q) : T(q) {}
virtual void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1) =0;
virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) =0;
private:
void IsolatedInitialize(const NameValuePairs &parameters) {assert(false);}
bool IsolatedFlush(bool hardFlush, bool blocking) {assert(false); return false;}
};
template <class T>
class CRYPTOPP_NO_VTABLE Multichannel : public CustomSignalPropagation<T>
class CRYPTOPP_NO_VTABLE CustomSignalPropagation : public CustomFlushPropagation<T>
{
public:
CustomSignalPropagation() {}
CustomSignalPropagation(BufferedTransformation *q) : CustomFlushPropagation<T>(q) {}
virtual void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1) =0;
private:
void IsolatedInitialize(const NameValuePairs &parameters) {assert(false);}
};
template <class T>
class CRYPTOPP_NO_VTABLE Multichannel : public CustomFlushPropagation<T>
{
public:
Multichannel() {}
Multichannel(BufferedTransformation *q) : CustomSignalPropagation<T>(q) {}
Multichannel(BufferedTransformation *q) : CustomFlushPropagation<T>(q) {}
void Initialize(const NameValuePairs &parameters, int propagation)
{ChannelInitialize(NULL_CHANNEL, parameters, propagation);}
bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
{return ChannelFlush(NULL_CHANNEL, hardFlush, propagation, blocking);}
bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
@ -154,7 +163,6 @@ public:
unsigned int ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking)
{return ChannelPut2(channel, begin, length, messageEnd, blocking);}
virtual void ChannelInitialize(const std::string &channel, const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1) =0;
virtual bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true) =0;
};