cryptlib.h

Go to the documentation of this file.
00001 // cryptlib.h - written and placed in the public domain by Wei Dai
00002 /*! \file
00003     This file contains the declarations for the abstract base
00004     classes that provide a uniform interface to this library.
00005 */
00006 
00007 /*! \mainpage Crypto++ Library 5.5 Reference Manual
00008 <dl>
00009 <dt>Abstract Base Classes<dd>
00010     cryptlib.h
00011 <dt>Symmetric Ciphers<dd>
00012     SymmetricCipherDocumentation
00013 <dt>Hash Functions<dd>
00014     MD2, MD4, MD5, RIPEMD160, RIPEMD320, RIPEMD128, RIPEMD256, SHA1, SHA224, SHA256, SHA384, SHA512, Tiger, Whirlpool
00015 <dt>Non-Cryptographic Checksums<dd>
00016     CRC32, Adler32
00017 <dt>Message Authentication Codes<dd>
00018     VMAC, HMAC, CBC_MAC, DMAC, TTMAC
00019 <dt>Random Number Generators<dd>
00020     NullRNG(), LC_RNG, RandomPool, BlockingRng, NonblockingRng, AutoSeededRandomPool, AutoSeededX917RNG, DefaultAutoSeededRNG
00021 <dt>Password-based Cryptography<dd>
00022     PasswordBasedKeyDerivationFunction
00023 <dt>Public Key Cryptosystems<dd>
00024     DLIES, ECIES, LUCES, RSAES, RabinES, LUC_IES
00025 <dt>Public Key Signature Schemes<dd>
00026     DSA, GDSA, ECDSA, NR, ECNR, LUCSS, RSASS, RSASS_ISO, RabinSS, RWSS, ESIGN
00027 <dt>Key Agreement<dd>
00028     #DH, DH2, #MQV, ECDH, ECMQV, XTR_DH
00029 <dt>Algebraic Structures<dd>
00030     Integer, PolynomialMod2, PolynomialOver, RingOfPolynomialsOver,
00031     ModularArithmetic, MontgomeryRepresentation, GFP2_ONB,
00032     GF2NP, GF256, GF2_32, EC2N, ECP
00033 <dt>Secret Sharing and Information Dispersal<dd>
00034     SecretSharing, SecretRecovery, InformationDispersal, InformationRecovery
00035 <dt>Compression<dd>
00036     Deflator, Inflator, Gzip, Gunzip, ZlibCompressor, ZlibDecompressor
00037 <dt>Input Source Classes<dd>
00038     StringSource, ArraySource, FileSource, SocketSource, WindowsPipeSource, RandomNumberSource
00039 <dt>Output Sink Classes<dd>
00040     StringSinkTemplate, ArraySink, FileSink, SocketSink, WindowsPipeSink, RandomNumberSink
00041 <dt>Filter Wrappers<dd>
00042     StreamTransformationFilter, HashFilter, HashVerificationFilter, SignerFilter, SignatureVerificationFilter
00043 <dt>Binary to Text Encoders and Decoders<dd>
00044     HexEncoder, HexDecoder, Base64Encoder, Base64Decoder, Base32Encoder, Base32Decoder
00045 <dt>Wrappers for OS features<dd>
00046     Timer, Socket, WindowsHandle, ThreadLocalStorage, ThreadUserTimer
00047 <dt>FIPS 140 related<dd>
00048     fips140.h
00049 </dl>
00050 
00051 In the FIPS 140-2 validated DLL version of Crypto++, only the following implementation class are available.
00052 <dl>
00053 <dt>Block Ciphers<dd>
00054     AES, DES_EDE2, DES_EDE3, SKIPJACK
00055 <dt>Cipher Modes (replace template parameter BC with one of the block ciphers above)<dd>
00056     ECB_Mode<BC>, CTR_Mode<BC>, CBC_Mode<BC>, CFB_FIPS_Mode<BC>, OFB_Mode<BC>
00057 <dt>Hash Functions<dd>
00058     SHA1, SHA224, SHA256, SHA384, SHA512
00059 <dt>Public Key Signature Schemes (replace template parameter H with one of the hash functions above)<dd>
00060     RSASS<PKCS1v15, H>, RSASS<PSS, H>, RSASS_ISO<H>, RWSS<P1363_EMSA2, H>, DSA, ECDSA<ECP, H>, ECDSA<EC2N, H>
00061 <dt>Message Authentication Codes (replace template parameter H with one of the hash functions above)<dd>
00062     HMAC<H>, CBC_MAC<DES_EDE2>, CBC_MAC<DES_EDE3>
00063 <dt>Random Number Generators<dd>
00064     DefaultAutoSeededRNG (AutoSeededX917RNG<AES>)
00065 <dt>Key Agreement<dd>
00066     #DH
00067 <dt>Public Key Cryptosystems<dd>
00068     RSAES<OAEP<SHA1> >
00069 </dl>
00070 
00071 <p>This reference manual is a work in progress. Some classes are still lacking detailed descriptions.
00072 <p>Thanks to Ryan Phillips for providing the Doxygen configuration file
00073 and getting me started with this manual.
00074 */
00075 
00076 #ifndef CRYPTOPP_CRYPTLIB_H
00077 #define CRYPTOPP_CRYPTLIB_H
00078 
00079 #include "config.h"
00080 #include "stdcpp.h"
00081 
00082 NAMESPACE_BEGIN(CryptoPP)
00083 
00084 // forward declarations
00085 class Integer;
00086 class RandomNumberGenerator;
00087 class BufferedTransformation;
00088 
00089 //! used to specify a direction for a cipher to operate in (encrypt or decrypt)
00090 enum CipherDir {ENCRYPTION, DECRYPTION};
00091 
00092 //! used to represent infinite time
00093 const unsigned long INFINITE_TIME = ULONG_MAX;
00094 
00095 // VC60 workaround: using enums as template parameters causes problems
00096 template <typename ENUM_TYPE, int VALUE>
00097 struct EnumToType
00098 {
00099     static ENUM_TYPE ToEnum() {return (ENUM_TYPE)VALUE;}
00100 };
00101 
00102 enum ByteOrder {LITTLE_ENDIAN_ORDER = 0, BIG_ENDIAN_ORDER = 1};
00103 typedef EnumToType<ByteOrder, LITTLE_ENDIAN_ORDER> LittleEndian;
00104 typedef EnumToType<ByteOrder, BIG_ENDIAN_ORDER> BigEndian;
00105 
00106 //! base class for all exceptions thrown by Crypto++
00107 class CRYPTOPP_DLL Exception : public std::exception
00108 {
00109 public:
00110     //! error types
00111     enum ErrorType {
00112         //! a method is not implemented
00113         NOT_IMPLEMENTED,
00114         //! invalid function argument
00115         INVALID_ARGUMENT,
00116         //! BufferedTransformation received a Flush(true) signal but can't flush buffers
00117         CANNOT_FLUSH,
00118         //! data integerity check (such as CRC or MAC) failed
00119         DATA_INTEGRITY_CHECK_FAILED,
00120         //! received input data that doesn't conform to expected format
00121         INVALID_DATA_FORMAT,
00122         //! error reading from input device or writing to output device
00123         IO_ERROR,
00124         //! some error not belong to any of the above categories
00125         OTHER_ERROR
00126     };
00127 
00128     explicit Exception(ErrorType errorType, const std::string &s) : m_errorType(errorType), m_what(s) {}
00129     virtual ~Exception() throw() {}
00130     const char *what() const throw() {return (m_what.c_str());}
00131     const std::string &GetWhat() const {return m_what;}
00132     void SetWhat(const std::string &s) {m_what = s;}
00133     ErrorType GetErrorType() const {return m_errorType;}
00134     void SetErrorType(ErrorType errorType) {m_errorType = errorType;}
00135 
00136 private:
00137     ErrorType m_errorType;
00138     std::string m_what;
00139 };
00140 
00141 //! exception thrown when an invalid argument is detected
00142 class CRYPTOPP_DLL InvalidArgument : public Exception
00143 {
00144 public:
00145     explicit InvalidArgument(const std::string &s) : Exception(INVALID_ARGUMENT, s) {}
00146 };
00147 
00148 //! exception thrown when input data is received that doesn't conform to expected format
00149 class CRYPTOPP_DLL InvalidDataFormat : public Exception
00150 {
00151 public:
00152     explicit InvalidDataFormat(const std::string &s) : Exception(INVALID_DATA_FORMAT, s) {}
00153 };
00154 
00155 //! exception thrown by decryption filters when trying to decrypt an invalid ciphertext
00156 class CRYPTOPP_DLL InvalidCiphertext : public InvalidDataFormat
00157 {
00158 public:
00159     explicit InvalidCiphertext(const std::string &s) : InvalidDataFormat(s) {}
00160 };
00161 
00162 //! exception thrown by a class if a non-implemented method is called
00163 class CRYPTOPP_DLL NotImplemented : public Exception
00164 {
00165 public:
00166     explicit NotImplemented(const std::string &s) : Exception(NOT_IMPLEMENTED, s) {}
00167 };
00168 
00169 //! exception thrown by a class when Flush(true) is called but it can't completely flush its buffers
00170 class CRYPTOPP_DLL CannotFlush : public Exception
00171 {
00172 public:
00173     explicit CannotFlush(const std::string &s) : Exception(CANNOT_FLUSH, s) {}
00174 };
00175 
00176 //! error reported by the operating system
00177 class CRYPTOPP_DLL OS_Error : public Exception
00178 {
00179 public:
00180     OS_Error(ErrorType errorType, const std::string &s, const std::string& operation, int errorCode)
00181         : Exception(errorType, s), m_operation(operation), m_errorCode(errorCode) {}
00182     ~OS_Error() throw() {}
00183 
00184     // the operating system API that reported the error
00185     const std::string & GetOperation() const {return m_operation;}
00186     // the error code return by the operating system
00187     int GetErrorCode() const {return m_errorCode;}
00188 
00189 protected:
00190     std::string m_operation;
00191     int m_errorCode;
00192 };
00193 
00194 //! used to return decoding results
00195 struct CRYPTOPP_DLL DecodingResult
00196 {
00197     explicit DecodingResult() : isValidCoding(false), messageLength(0) {}
00198     explicit DecodingResult(size_t len) : isValidCoding(true), messageLength(len) {}
00199 
00200     bool operator==(const DecodingResult &rhs) const {return isValidCoding == rhs.isValidCoding && messageLength == rhs.messageLength;}
00201     bool operator!=(const DecodingResult &rhs) const {return !operator==(rhs);}
00202 
00203     bool isValidCoding;
00204     size_t messageLength;
00205 
00206 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
00207     operator size_t() const {return isValidCoding ? messageLength : 0;}
00208 #endif
00209 };
00210 
00211 //! interface for retrieving values given their names
00212 /*! \note This class is used to safely pass a variable number of arbitrarily typed arguments to functions
00213     and to read values from keys and crypto parameters.
00214     \note To obtain an object that implements NameValuePairs for the purpose of parameter
00215     passing, use the MakeParameters() function.
00216     \note To get a value from NameValuePairs, you need to know the name and the type of the value. 
00217     Call GetValueNames() on a NameValuePairs object to obtain a list of value names that it supports.
00218     Then look at the Name namespace documentation to see what the type of each value is, or
00219     alternatively, call GetIntValue() with the value name, and if the type is not int, a
00220     ValueTypeMismatch exception will be thrown and you can get the actual type from the exception object.
00221 */
00222 class CRYPTOPP_NO_VTABLE NameValuePairs
00223 {
00224 public:
00225     virtual ~NameValuePairs() {}
00226 
00227     //! exception thrown when trying to retrieve a value using a different type than expected
00228     class CRYPTOPP_DLL ValueTypeMismatch : public InvalidArgument
00229     {
00230     public:
00231         ValueTypeMismatch(const std::string &name, const std::type_info &stored, const std::type_info &retrieving)
00232             : InvalidArgument("NameValuePairs: type mismatch for '" + name + "', stored '" + stored.name() + "', trying to retrieve '" + retrieving.name() + "'")
00233             , m_stored(stored), m_retrieving(retrieving) {}
00234 
00235         const std::type_info & GetStoredTypeInfo() const {return m_stored;}
00236         const std::type_info & GetRetrievingTypeInfo() const {return m_retrieving;}
00237 
00238     private:
00239         const std::type_info &m_stored;
00240         const std::type_info &m_retrieving;
00241     };
00242 
00243     //! get a copy of this object or a subobject of it
00244     template <class T>
00245     bool GetThisObject(T &object) const
00246     {
00247         return GetValue((std::string("ThisObject:")+typeid(T).name()).c_str(), object);
00248     }
00249 
00250     //! get a pointer to this object, as a pointer to T
00251     template <class T>
00252     bool GetThisPointer(T *&p) const
00253     {
00254         return GetValue((std::string("ThisPointer:")+typeid(T).name()).c_str(), p);
00255     }
00256 
00257     //! get a named value, returns true if the name exists
00258     template <class T>
00259     bool GetValue(const char *name, T &value) const
00260     {
00261         return GetVoidValue(name, typeid(T), &value);
00262     }
00263 
00264     //! get a named value, returns the default if the name doesn't exist
00265     template <class T>
00266     T GetValueWithDefault(const char *name, T defaultValue) const
00267     {
00268         GetValue(name, defaultValue);
00269         return defaultValue;
00270     }
00271 
00272     //! get a list of value names that can be retrieved
00273     CRYPTOPP_DLL std::string GetValueNames() const
00274         {std::string result; GetValue("ValueNames", result); return result;}
00275 
00276     //! get a named value with type int
00277     /*! used to ensure we don't accidentally try to get an unsigned int
00278         or some other type when we mean int (which is the most common case) */
00279     CRYPTOPP_DLL bool GetIntValue(const char *name, int &value) const
00280         {return GetValue(name, value);}
00281 
00282     //! get a named value with type int, with default
00283     CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const
00284         {return GetValueWithDefault(name, defaultValue);}
00285 
00286     //! used by derived classes to check for type mismatch
00287     CRYPTOPP_DLL static void CRYPTOPP_API ThrowIfTypeMismatch(const char *name, const std::type_info &stored, const std::type_info &retrieving)
00288         {if (stored != retrieving) throw ValueTypeMismatch(name, stored, retrieving);}
00289 
00290     template <class T>
00291     void GetRequiredParameter(const char *className, const char *name, T &value) const
00292     {
00293         if (!GetValue(name, value))
00294             throw InvalidArgument(std::string(className) + ": missing required parameter '" + name + "'");
00295     }
00296 
00297     CRYPTOPP_DLL void GetRequiredIntParameter(const char *className, const char *name, int &value) const
00298     {
00299         if (!GetIntValue(name, value))
00300             throw InvalidArgument(std::string(className) + ": missing required parameter '" + name + "'");
00301     }
00302 
00303     //! to be implemented by derived classes, users should use one of the above functions instead
00304     CRYPTOPP_DLL virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const =0;
00305 };
00306 
00307 //! namespace containing value name definitions
00308 /*! value names, types and semantics:
00309 
00310     ThisObject:ClassName (ClassName, copy of this object or a subobject)
00311     ThisPointer:ClassName (const ClassName *, pointer to this object or a subobject)
00312 */
00313 DOCUMENTED_NAMESPACE_BEGIN(Name)
00314 // more names defined in argnames.h
00315 DOCUMENTED_NAMESPACE_END
00316 
00317 //! empty set of name-value pairs
00318 class CRYPTOPP_DLL NullNameValuePairs : public NameValuePairs
00319 {
00320 public:
00321     bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const {return false;}
00322 };
00323 
00324 //! _
00325 extern CRYPTOPP_DLL const NullNameValuePairs g_nullNameValuePairs;
00326 
00327 // ********************************************************
00328 
00329 //! interface for cloning objects, this is not implemented by most classes yet
00330 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Clonable
00331 {
00332 public:
00333     virtual ~Clonable() {}
00334     //! this is not implemented by most classes yet
00335     virtual Clonable* Clone() const {throw NotImplemented("Clone() is not implemented yet.");}  // TODO: make this =0
00336 };
00337 
00338 //! interface for all crypto algorithms
00339 
00340 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Algorithm : public Clonable
00341 {
00342 public:
00343     /*! When FIPS 140-2 compliance is enabled and checkSelfTestStatus == true,
00344         this constructor throws SelfTestFailure if the self test hasn't been run or fails. */
00345     Algorithm(bool checkSelfTestStatus = true);
00346     //! returns name of this algorithm, not universally implemented yet
00347     virtual std::string AlgorithmName() const {return "unknown";}
00348 };
00349 
00350 //! keying interface for crypto algorithms that take byte strings as keys
00351 
00352 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyingInterface
00353 {
00354 public:
00355     //! returns smallest valid key length in bytes */
00356     virtual size_t MinKeyLength() const =0;
00357     //! returns largest valid key length in bytes */
00358     virtual size_t MaxKeyLength() const =0;
00359     //! returns default (recommended) key length in bytes */
00360     virtual size_t DefaultKeyLength() const =0;
00361 
00362     //! returns the smallest valid key length in bytes that is >= min(n, GetMaxKeyLength())
00363     virtual size_t GetValidKeyLength(size_t n) const =0;
00364 
00365     //! returns whether n is a valid key length
00366     virtual bool IsValidKeyLength(size_t n) const
00367         {return n == GetValidKeyLength(n);}
00368 
00369     //! set or reset the key of this object
00370     /*! \param params is used to specify Rounds, BlockSize, etc */
00371     virtual void SetKey(const byte *key, size_t length, const NameValuePairs &params = g_nullNameValuePairs);
00372 
00373     //! calls SetKey() with an NameValuePairs object that just specifies "Rounds"
00374     void SetKeyWithRounds(const byte *key, size_t length, int rounds);
00375 
00376     //! calls SetKey() with an NameValuePairs object that just specifies "IV"
00377     void SetKeyWithIV(const byte *key, size_t length, const byte *iv);
00378 
00379     enum IV_Requirement {UNIQUE_IV = 0, RANDOM_IV, UNPREDICTABLE_RANDOM_IV, INTERNALLY_GENERATED_IV, NOT_RESYNCHRONIZABLE};
00380     //! returns the minimal requirement for secure IVs
00381     virtual IV_Requirement IVRequirement() const =0;
00382 
00383     //! returns whether this object can be resynchronized (i.e. supports initialization vectors)
00384     /*! If this function returns true, and no IV is passed to SetKey() and CanUseStructuredIVs()==true, an IV of all 0's will be assumed. */
00385     bool IsResynchronizable() const {return IVRequirement() < NOT_RESYNCHRONIZABLE;}
00386     //! returns whether this object can use random IVs (in addition to ones returned by GetNextIV)
00387     bool CanUseRandomIVs() const {return IVRequirement() <= UNPREDICTABLE_RANDOM_IV;}
00388     //! returns whether this object can use random but possibly predictable IVs (in addition to ones returned by GetNextIV)
00389     bool CanUsePredictableIVs() const {return IVRequirement() <= RANDOM_IV;}
00390     //! returns whether this object can use structured IVs, for example a counter (in addition to ones returned by GetNextIV)
00391     bool CanUseStructuredIVs() const {return IVRequirement() <= UNIQUE_IV;}
00392 
00393     //! returns size of IVs used by this object
00394     virtual unsigned int IVSize() const {throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");}
00395     //! resynchronize with an IV
00396     virtual void Resynchronize(const byte *IV) {throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");}
00397     //! get a secure IV for the next message
00398     /*! This method should be called after you finish encrypting one message and are ready to start the next one.
00399         After calling it, you must call SetKey() or Resynchronize() before using this object again. 
00400         This method is not implemented on decryption objects. */
00401     virtual void GetNextIV(RandomNumberGenerator &rng, byte *IV);
00402 
00403 protected:
00404     virtual const Algorithm & GetAlgorithm() const =0;
00405     virtual void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params) =0;
00406 
00407     void ThrowIfInvalidKeyLength(size_t length);
00408     void ThrowIfResynchronizable();         // to be called when no IV is passed
00409     void ThrowIfInvalidIV(const byte *iv);  // check for NULL IV if it can't be used
00410     const byte * GetIVAndThrowIfInvalid(const NameValuePairs &params);
00411     inline void AssertValidKeyLength(size_t length) const
00412         {assert(IsValidKeyLength(length));}
00413 };
00414 
00415 //! interface for the data processing part of block ciphers
00416 
00417 /*! Classes derived from BlockTransformation are block ciphers
00418     in ECB mode (for example the DES::Encryption class), which are stateless,
00419     and they can make assumptions about the memory alignment of their inputs and outputs.
00420     These classes should not be used directly, but only in combination with
00421     a mode class (see CipherModeDocumentation in modes.h).
00422 */
00423 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockTransformation : public Algorithm
00424 {
00425 public:
00426     //! encrypt or decrypt inBlock, xor with xorBlock, and write to outBlock
00427     virtual void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const =0;
00428 
00429     //! encrypt or decrypt one block
00430     /*! \pre size of inBlock and outBlock == BlockSize() */
00431     void ProcessBlock(const byte *inBlock, byte *outBlock) const
00432         {ProcessAndXorBlock(inBlock, NULL, outBlock);}
00433 
00434     //! encrypt or decrypt one block in place
00435     void ProcessBlock(byte *inoutBlock) const
00436         {ProcessAndXorBlock(inoutBlock, NULL, inoutBlock);}
00437 
00438     //! block size of the cipher in bytes
00439     virtual unsigned int BlockSize() const =0;
00440 
00441     //! block pointers must be divisible by this
00442     virtual unsigned int BlockAlignment() const;    // returns alignment of word32 by default
00443 
00444     //! returns true if this is a permutation (i.e. there is an inverse transformation)
00445     virtual bool IsPermutation() const {return true;}
00446 
00447     //! returns true if this is an encryption object
00448     virtual bool IsForwardTransformation() const =0;
00449 
00450     //! return number of blocks that can be processed in parallel, for bit-slicing implementations
00451     virtual unsigned int OptimalNumberOfParallelBlocks() const {return 1;}
00452 
00453     //! encrypt or decrypt multiple blocks, for bit-slicing implementations
00454     virtual void ProcessAndXorMultipleBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t numberOfBlocks) const;
00455 
00456     inline CipherDir GetCipherDirection() const {return IsForwardTransformation() ? ENCRYPTION : DECRYPTION;}
00457 };
00458 
00459 //! interface for the data processing part of stream ciphers
00460 
00461 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE StreamTransformation : public Algorithm
00462 {
00463 public:
00464     //! return a reference to this object, 
00465     /*! This function is useful for passing a temporary StreamTransformation object to a 
00466         function that takes a non-const reference. */
00467     StreamTransformation& Ref() {return *this;}
00468 
00469     //! returns block size, if input must be processed in blocks, otherwise 1
00470     virtual unsigned int MandatoryBlockSize() const {return 1;}
00471 
00472     //! returns the input block size that is most efficient for this cipher
00473     /*! \note optimal input length is n * OptimalBlockSize() - GetOptimalBlockSizeUsed() for any n > 0 */
00474     virtual unsigned int OptimalBlockSize() const {return MandatoryBlockSize();}
00475     //! returns how much of the current block is used up
00476     virtual unsigned int GetOptimalBlockSizeUsed() const {return 0;}
00477 
00478     //! returns how input should be aligned for optimal performance
00479     virtual unsigned int OptimalDataAlignment() const {return 1;}
00480 
00481     //! encrypt or decrypt an array of bytes of specified length
00482     /*! \note either inString == outString, or they don't overlap */
00483     virtual void ProcessData(byte *outString, const byte *inString, size_t length) =0;
00484 
00485     //! for ciphers where the last block of data is special, encrypt or decrypt the last block of data
00486     /*! For now the only use of this function is for CBC-CTS mode. */
00487     virtual void ProcessLastBlock(byte *outString, const byte *inString, size_t length);
00488     //! returns the minimum size of the last block, 0 indicating the last block is not special
00489     virtual unsigned int MinLastBlockSize() const {return 0;}
00490 
00491     //! same as ProcessData(inoutString, inoutString, length)
00492     inline void ProcessString(byte *inoutString, size_t length)
00493         {ProcessData(inoutString, inoutString, length);}
00494     //! same as ProcessData(outString, inString, length)
00495     inline void ProcessString(byte *outString, const byte *inString, size_t length)
00496         {ProcessData(outString, inString, length);}
00497     //! implemented as {ProcessData(&input, &input, 1); return input;}
00498     inline byte ProcessByte(byte input)
00499         {ProcessData(&input, &input, 1); return input;}
00500 
00501     //! returns whether this cipher supports random access
00502     virtual bool IsRandomAccess() const =0;
00503     //! for random access ciphers, seek to an absolute position
00504     virtual void Seek(lword n)
00505     {
00506         assert(!IsRandomAccess());
00507         throw NotImplemented("StreamTransformation: this object doesn't support random access");
00508     }
00509 
00510     //! returns whether this transformation is self-inverting (e.g. xor with a keystream)
00511     virtual bool IsSelfInverting() const =0;
00512     //! returns whether this is an encryption object
00513     virtual bool IsForwardTransformation() const =0;
00514 };
00515 
00516 //! interface for hash functions and data processing part of MACs
00517 
00518 /*! HashTransformation objects are stateful.  They are created in an initial state,
00519     change state as Update() is called, and return to the initial
00520     state when Final() is called.  This interface allows a large message to
00521     be hashed in pieces by calling Update() on each piece followed by
00522     calling Final().
00523 */
00524 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE HashTransformation : public Algorithm
00525 {
00526 public:
00527     //! return a reference to this object, 
00528     /*! This function is useful for passing a temporary HashTransformation object to a 
00529         function that takes a non-const reference. */
00530     HashTransformation& Ref() {return *this;}
00531 
00532     //! process more input
00533     virtual void Update(const byte *input, size_t length) =0;
00534 
00535     //! request space to write input into
00536     virtual byte * CreateUpdateSpace(size_t &size) {size=0; return NULL;}
00537 
00538     //! compute hash for current message, then restart for a new message
00539     /*! \pre size of digest == DigestSize(). */
00540     virtual void Final(byte *digest)
00541         {TruncatedFinal(digest, DigestSize());}
00542 
00543     //! discard the current state, and restart with a new message
00544     virtual void Restart()
00545         {TruncatedFinal(NULL, 0);}
00546 
00547     //! size of the hash returned by Final()
00548     virtual unsigned int DigestSize() const =0;
00549 
00550     //! block size of underlying compression function, or 0 if not block based
00551     virtual unsigned int BlockSize() const {return 0;}
00552 
00553     //! input to Update() should have length a multiple of this for optimal speed
00554     virtual unsigned int OptimalBlockSize() const {return 1;}
00555 
00556     //! returns how input should be aligned for optimal performance
00557     virtual unsigned int OptimalDataAlignment() const {return 1;}
00558 
00559     //! use this if your input is in one piece and you don't want to call Update() and Final() separately
00560     virtual void CalculateDigest(byte *digest, const byte *input, size_t length)
00561         {Update(input, length); Final(digest);}
00562 
00563     //! verify that digest is a valid digest for the current message, then reinitialize the object
00564     /*! Default implementation is to call Final() and do a bitwise comparison
00565         between its output and digest. */
00566     virtual bool Verify(const byte *digest)
00567         {return TruncatedVerify(digest, DigestSize());}
00568 
00569     //! use this if your input is in one piece and you don't want to call Update() and Verify() separately
00570     virtual bool VerifyDigest(const byte *digest, const byte *input, size_t length)
00571         {Update(input, length); return Verify(digest);}
00572 
00573     //! truncated version of Final()
00574     virtual void TruncatedFinal(byte *digest, size_t digestSize) =0;
00575 
00576     //! truncated version of CalculateDigest()
00577     virtual void CalculateTruncatedDigest(byte *digest, size_t digestSize, const byte *input, size_t length)
00578         {Update(input, length); TruncatedFinal(digest, digestSize);}
00579 
00580     //! truncated version of Verify()
00581     virtual bool TruncatedVerify(const byte *digest, size_t digestLength);
00582 
00583     //! truncated version of VerifyDigest()
00584     virtual bool VerifyTruncatedDigest(const byte *digest, size_t digestLength, const byte *input, size_t length)
00585         {Update(input, length); return TruncatedVerify(digest, digestLength);}
00586 
00587 protected:
00588     void ThrowIfInvalidTruncatedSize(size_t size) const;
00589 };
00590 
00591 typedef HashTransformation HashFunction;
00592 
00593 template <class T>
00594 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyedTransformation : public T, public SimpleKeyingInterface
00595 {
00596 protected:
00597     const Algorithm & GetAlgorithm() const {return *this;}
00598 };
00599 
00600 #ifdef CRYPTOPP_DOXYGEN_PROCESSING
00601 //! interface for one direction (encryption or decryption) of a block cipher
00602 /*! \note These objects usually should not be used directly. See BlockTransformation for more details. */
00603 class BlockCipher : public BlockTransformation, public SimpleKeyingInterface {};
00604 //! interface for one direction (encryption or decryption) of a stream cipher or cipher mode
00605 class SymmetricCipher : public StreamTransformation, public SimpleKeyingInterface {};
00606 //! interface for message authentication codes
00607 class MessageAuthenticationCode : public HashTransformation, public SimpleKeyingInterface {};
00608 #else
00609 typedef SimpleKeyedTransformation<BlockTransformation> BlockCipher;
00610 typedef SimpleKeyedTransformation<StreamTransformation> SymmetricCipher;
00611 typedef SimpleKeyedTransformation<HashTransformation> MessageAuthenticationCode;
00612 #endif
00613 
00614 CRYPTOPP_DLL_TEMPLATE_CLASS SimpleKeyedTransformation<BlockTransformation>;
00615 CRYPTOPP_DLL_TEMPLATE_CLASS SimpleKeyedTransformation<StreamTransformation>;
00616 CRYPTOPP_DLL_TEMPLATE_CLASS SimpleKeyedTransformation<HashTransformation>;
00617 
00618 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
00619 typedef SymmetricCipher StreamCipher;
00620 #endif
00621 
00622 //! interface for random number generators
00623 /*! All return values are uniformly distributed over the range specified.
00624 */
00625 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomNumberGenerator : public Algorithm
00626 {
00627 public:
00628     //! update RNG state with additional unpredictable values
00629     virtual void IncorporateEntropy(const byte *input, size_t length) {throw NotImplemented("RandomNumberGenerator: IncorporateEntropy not implemented");}
00630 
00631     //! returns true if IncorporateEntropy is implemented
00632     virtual bool CanIncorporateEntropy() const {return false;}
00633 
00634     //! generate new random byte and return it
00635     virtual byte GenerateByte();
00636 
00637     //! generate new random bit and return it
00638     /*! Default implementation is to call GenerateByte() and return its lowest bit. */
00639     virtual unsigned int GenerateBit();
00640 
00641     //! generate a random 32 bit word in the range min to max, inclusive
00642     virtual word32 GenerateWord32(word32 a=0, word32 b=0xffffffffL);
00643 
00644     //! generate random array of bytes
00645     virtual void GenerateBlock(byte *output, size_t size);
00646 
00647     //! generate and discard n bytes
00648     virtual void DiscardBytes(size_t n);
00649 
00650     //! generate random bytes as input to a BufferedTransformation
00651     virtual void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length);
00652 
00653     //! randomly shuffle the specified array, resulting permutation is uniformly distributed
00654     template <class IT> void Shuffle(IT begin, IT end)
00655     {
00656         for (; begin != end; ++begin)
00657             std::iter_swap(begin, begin + GenerateWord32(0, end-begin-1));
00658     }
00659 
00660 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
00661     byte GetByte() {return GenerateByte();}
00662     unsigned int GetBit() {return GenerateBit();}
00663     word32 GetLong(word32 a=0, word32 b=0xffffffffL) {return GenerateWord32(a, b);}
00664     word16 GetShort(word16 a=0, word16 b=0xffff) {return (word16)GenerateWord32(a, b);}
00665     void GetBlock(byte *output, size_t size) {GenerateBlock(output, size);}
00666 #endif
00667 };
00668 
00669 //! returns a reference that can be passed to functions that ask for a RNG but doesn't actually use it
00670 CRYPTOPP_DLL RandomNumberGenerator & CRYPTOPP_API NullRNG();
00671 
00672 class WaitObjectContainer;
00673 class CallStack;
00674 
00675 //! interface for objects that you can wait for
00676 
00677 class CRYPTOPP_NO_VTABLE Waitable
00678 {
00679 public:
00680     //! maximum number of wait objects that this object can return
00681     virtual unsigned int GetMaxWaitObjectCount() const =0;
00682     //! put wait objects into container
00683     /*! \param callStack is used for tracing no wait loops, example:
00684                  something.GetWaitObjects(c, CallStack("my func after X", 0));
00685                - or in an outer GetWaitObjects() method that itself takes a callStack parameter:
00686                  innerThing.GetWaitObjects(c, CallStack("MyClass::GetWaitObjects at X", &callStack)); */
00687     virtual void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) =0;
00688     //! wait on this object
00689     /*! same as creating an empty container, calling GetWaitObjects(), and calling Wait() on the container */
00690     bool Wait(unsigned long milliseconds, CallStack const& callStack);
00691 };
00692 
00693 //! interface for buffered transformations
00694 
00695 /*! BufferedTransformation is a generalization of BlockTransformation,
00696     StreamTransformation, and HashTransformation.
00697 
00698     A buffered transformation is an object that takes a stream of bytes
00699     as input (this may be done in stages), does some computation on them, and
00700     then places the result into an internal buffer for later retrieval.  Any
00701     partial result already in the output buffer is not modified by further
00702     input.
00703 
00704     If a method takes a "blocking" parameter, and you
00705     pass "false" for it, the method will return before all input has been processed if
00706     the input cannot be processed without waiting (for network buffers to become available, for example).
00707     In this case the method will return true
00708     or a non-zero integer value. When this happens you must continue to call the method with the same
00709     parameters until it returns false or zero, before calling any other method on it or
00710     attached BufferedTransformation. The integer return value in this case is approximately
00711     the number of bytes left to be processed, and can be used to implement a progress bar.
00712 
00713     For functions that take a "propagation" parameter, propagation != 0 means pass on the signal to attached
00714     BufferedTransformation objects, with propagation decremented at each step until it reaches 0.
00715     -1 means unlimited propagation.
00716 
00717     \nosubgrouping
00718 */
00719 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BufferedTransformation : public Algorithm, public Waitable
00720 {
00721 public:
00722     // placed up here for CW8
00723     static const std::string NULL_CHANNEL;  // the empty string ""
00724 
00725     BufferedTransformation() : Algorithm(false) {}
00726 
00727     //! return a reference to this object
00728     /*! This function is useful for passing a temporary BufferedTransformation object to a 
00729         function that takes a non-const reference. */
00730     BufferedTransformation& Ref() {return *this;}
00731 
00732     //! \name INPUT
00733     //@{
00734         //! input a byte for processing
00735         size_t Put(byte inByte, bool blocking=true)
00736             {return Put(&inByte, 1, blocking);}
00737         //! input multiple bytes
00738         size_t Put(const byte *inString, size_t length, bool blocking=true)
00739             {return Put2(inString, length, 0, blocking);}
00740 
00741         //! input a 16-bit word
00742         size_t PutWord16(word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
00743         //! input a 32-bit word
00744         size_t PutWord32(word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
00745 
00746         //! request space which can be written into by the caller, and then used as input to Put()
00747         /*! \param size is requested size (as a hint) for input, and size of the returned space for output */
00748         /*! \note The purpose of this method is to help avoid doing extra memory allocations. */
00749         virtual byte * CreatePutSpace(size_t &size) {size=0; return NULL;}
00750 
00751         virtual bool CanModifyInput() const {return false;}
00752 
00753         //! input multiple bytes that may be modified by callee
00754         size_t PutModifiable(byte *inString, size_t length, bool blocking=true)
00755             {return PutModifiable2(inString, length, 0, blocking);}
00756 
00757         bool MessageEnd(int propagation=-1, bool blocking=true)
00758             {return !!Put2(NULL, 0, propagation < 0 ? -1 : propagation+1, blocking);}
00759         size_t PutMessageEnd(const byte *inString, size_t length, int propagation=-1, bool blocking=true)
00760             {return Put2(inString, length, propagation < 0 ? -1 : propagation+1, blocking);}
00761 
00762         //! input multiple bytes for blocking or non-blocking processing
00763         /*! \param messageEnd means how many filters to signal MessageEnd to, including this one */
00764         virtual size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) =0;
00765         //! input multiple bytes that may be modified by callee for blocking or non-blocking processing
00766         /*! \param messageEnd means how many filters to signal MessageEnd to, including this one */
00767         virtual size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking)
00768             {return Put2(inString, length, messageEnd, blocking);}
00769 
00770         //! thrown by objects that have not implemented nonblocking input processing
00771         struct BlockingInputOnly : public NotImplemented
00772             {BlockingInputOnly(const std::string &s) : NotImplemented(s + ": Nonblocking input is not implemented by this object.") {}};
00773     //@}
00774 
00775     //! \name WAITING
00776     //@{
00777         unsigned int GetMaxWaitObjectCount() const;
00778         void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack);
00779     //@}
00780 
00781     //! \name SIGNALS
00782     //@{
00783         virtual void IsolatedInitialize(const NameValuePairs &parameters) {throw NotImplemented("BufferedTransformation: this object can't be reinitialized");}
00784         virtual bool IsolatedFlush(bool hardFlush, bool blocking) =0;
00785         virtual bool IsolatedMessageSeriesEnd(bool blocking) {return false;}
00786 
00787         //! initialize or reinitialize this object
00788         virtual void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
00789         //! flush buffered input and/or output
00790         /*! \param hardFlush is used to indicate whether all data should be flushed
00791             \note Hard flushes must be used with care. It means try to process and output everything, even if
00792             there may not be enough data to complete the action. For example, hard flushing a HexDecoder would
00793             cause an error if you do it after inputing an odd number of hex encoded characters.
00794             For some types of filters, for example ZlibDecompressor, hard flushes can only
00795             be done at "synchronization points". These synchronization points are positions in the data
00796             stream that are created by hard flushes on the corresponding reverse filters, in this
00797             example ZlibCompressor. This is useful when zlib compressed data is moved across a
00798             network in packets and compression state is preserved across packets, as in the ssh2 protocol.
00799         */
00800         virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true);
00801         //! mark end of a series of messages
00802         /*! There should be a MessageEnd immediately before MessageSeriesEnd. */
00803         virtual bool MessageSeriesEnd(int propagation=-1, bool blocking=true);
00804 
00805         //! set propagation of automatically generated and transferred signals
00806         /*! propagation == 0 means do not automaticly generate signals */
00807         virtual void SetAutoSignalPropagation(int propagation) {}
00808 
00809         //!
00810         virtual int GetAutoSignalPropagation() const {return 0;}
00811 public:
00812 
00813 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
00814         void Close() {MessageEnd();}
00815 #endif
00816     //@}
00817 
00818     //! \name RETRIEVAL OF ONE MESSAGE
00819     //@{
00820         //! returns number of bytes that is currently ready for retrieval
00821         /*! All retrieval functions return the actual number of bytes
00822             retrieved, which is the lesser of the request number and
00823             MaxRetrievable(). */
00824         virtual lword MaxRetrievable() const;
00825 
00826         //! returns whether any bytes are currently ready for retrieval
00827         virtual bool AnyRetrievable() const;
00828 
00829         //! try to retrieve a single byte
00830         virtual size_t Get(byte &outByte);
00831         //! try to retrieve multiple bytes
00832         virtual size_t Get(byte *outString, size_t getMax);
00833 
00834         //! peek at the next byte without removing it from the output buffer
00835         virtual size_t Peek(byte &outByte) const;
00836         //! peek at multiple bytes without removing them from the output buffer
00837         virtual size_t Peek(byte *outString, size_t peekMax) const;
00838 
00839         //! try to retrieve a 16-bit word
00840         size_t GetWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER);
00841         //! try to retrieve a 32-bit word
00842         size_t GetWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER);
00843 
00844         //! try to peek at a 16-bit word
00845         size_t PeekWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER) const;
00846         //! try to peek at a 32-bit word
00847         size_t PeekWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER) const;
00848 
00849         //! move transferMax bytes of the buffered output to target as input
00850         lword TransferTo(BufferedTransformation &target, lword transferMax=LWORD_MAX, const std::string &channel=NULL_CHANNEL)
00851             {TransferTo2(target, transferMax, channel); return transferMax;}
00852 
00853         //! discard skipMax bytes from the output buffer
00854         virtual lword Skip(lword skipMax=LWORD_MAX);
00855 
00856         //! copy copyMax bytes of the buffered output to target as input
00857         lword CopyTo(BufferedTransformation &target, lword copyMax=LWORD_MAX, const std::string &channel=NULL_CHANNEL) const
00858             {return CopyRangeTo(target, 0, copyMax, channel);}
00859 
00860         //! copy copyMax bytes of the buffered output, starting at position (relative to current position), to target as input
00861         lword CopyRangeTo(BufferedTransformation &target, lword position, lword copyMax=LWORD_MAX, const std::string &channel=NULL_CHANNEL) const
00862             {lword i = position; CopyRangeTo2(target, i, i+copyMax, channel); return i-position;}
00863 
00864 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
00865         unsigned long MaxRetrieveable() const {return MaxRetrievable();}
00866 #endif
00867     //@}
00868 
00869     //! \name RETRIEVAL OF MULTIPLE MESSAGES
00870     //@{
00871         //!
00872         virtual lword TotalBytesRetrievable() const;
00873         //! number of times MessageEnd() has been received minus messages retrieved or skipped
00874         virtual unsigned int NumberOfMessages() const;
00875         //! returns true if NumberOfMessages() > 0
00876         virtual bool AnyMessages() const;
00877         //! start retrieving the next message
00878         /*!
00879             Returns false if no more messages exist or this message 
00880             is not completely retrieved.
00881         */
00882         virtual bool GetNextMessage();
00883         //! skip count number of messages
00884         virtual unsigned int SkipMessages(unsigned int count=UINT_MAX);
00885         //!
00886         unsigned int TransferMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=NULL_CHANNEL)
00887             {TransferMessagesTo2(target, count, channel); return count;}
00888         //!
00889         unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=NULL_CHANNEL) const;
00890 
00891         //!
00892         virtual void SkipAll();
00893         //!
00894         void TransferAllTo(BufferedTransformation &target, const std::string &channel=NULL_CHANNEL)
00895             {TransferAllTo2(target, channel);}
00896         //!
00897         void CopyAllTo(BufferedTransformation &target, const std::string &channel=NULL_CHANNEL) const;
00898 
00899         virtual bool GetNextMessageSeries() {return false;}
00900         virtual unsigned int NumberOfMessagesInThisSeries() const {return NumberOfMessages();}
00901         virtual unsigned int NumberOfMessageSeries() const {return 0;}
00902     //@}
00903 
00904     //! \name NON-BLOCKING TRANSFER OF OUTPUT
00905     //@{
00906         //! upon return, byteCount contains number of bytes that have finished being transfered, and returns the number of bytes left in the current transfer block
00907         virtual size_t TransferTo2(BufferedTransformation &target, lword &byteCount, const std::string &channel=NULL_CHANNEL, bool blocking=true) =0;
00908         //! upon return, begin contains the start position of data yet to be finished copying, and returns the number of bytes left in the current transfer block
00909         virtual size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const =0;
00910         //! upon return, messageCount contains number of messages that have finished being transfered, and returns the number of bytes left in the current transfer block
00911         size_t TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel=NULL_CHANNEL, bool blocking=true);
00912         //! returns the number of bytes left in the current transfer block
00913         size_t TransferAllTo2(BufferedTransformation &target, const std::string &channel=NULL_CHANNEL, bool blocking=true);
00914     //@}
00915 
00916     //! \name CHANNELS
00917     //@{
00918         struct NoChannelSupport : public NotImplemented
00919             {NoChannelSupport() : NotImplemented("BufferedTransformation: this object doesn't support multiple channels") {}};
00920 
00921         size_t ChannelPut(const std::string &channel, byte inByte, bool blocking=true)
00922             {return ChannelPut(channel, &inByte, 1, blocking);}
00923         size_t ChannelPut(const std::string &channel, const byte *inString, size_t length, bool blocking=true)
00924             {return ChannelPut2(channel, inString, length, 0, blocking);}
00925 
00926         size_t ChannelPutModifiable(const std::string &channel, byte *inString, size_t length, bool blocking=true)
00927             {return ChannelPutModifiable2(channel, inString, length, 0, blocking);}
00928 
00929         size_t ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
00930         size_t ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
00931 
00932         bool ChannelMessageEnd(const std::string &channel, int propagation=-1, bool blocking=true)
00933             {return !!ChannelPut2(channel, NULL, 0, propagation < 0 ? -1 : propagation+1, blocking);}
00934         size_t ChannelPutMessageEnd(const std::string &channel, const byte *inString, size_t length, int propagation=-1, bool blocking=true)
00935             {return ChannelPut2(channel, inString, length, propagation < 0 ? -1 : propagation+1, blocking);}
00936 
00937         virtual byte * ChannelCreatePutSpace(const std::string &channel, size_t &size);
00938 
00939         virtual size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking);
00940         virtual size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking);
00941 
00942         virtual bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true);
00943         virtual bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true);
00944 
00945         virtual void SetRetrievalChannel(const std::string &channel);
00946     //@}
00947 
00948     //! \name ATTACHMENT
00949     /*! Some BufferedTransformation objects (e.g. Filter objects)
00950         allow other BufferedTransformation objects to be attached. When
00951         this is done, the first object instead of buffering its output,
00952         sents that output to the attached object as input. The entire
00953         attachment chain is deleted when the anchor object is destructed.
00954     */
00955     //@{
00956         //! returns whether this object allows attachment
00957         virtual bool Attachable() {return false;}
00958         //! returns the object immediately attached to this object or NULL for no attachment
00959         virtual BufferedTransformation *AttachedTransformation() {assert(!Attachable()); return 0;}
00960         //!
00961         virtual const BufferedTransformation *AttachedTransformation() const
00962             {return const_cast<BufferedTransformation *>(this)->AttachedTransformation();}
00963         //! delete the current attachment chain and replace it with newAttachment
00964         virtual void Detach(BufferedTransformation *newAttachment = 0)
00965             {assert(!Attachable()); throw NotImplemented("BufferedTransformation: this object is not attachable");}
00966         //! add newAttachment to the end of attachment chain
00967         virtual void Attach(BufferedTransformation *newAttachment);
00968     //@}
00969 
00970 protected:
00971     static int DecrementPropagation(int propagation)
00972         {return propagation != 0 ? propagation - 1 : 0;}
00973 
00974 private:
00975     byte m_buf[4];  // for ChannelPutWord16 and ChannelPutWord32, to ensure buffer isn't deallocated before non-blocking operation completes
00976 };
00977 
00978 //! returns a reference to a BufferedTransformation object that discards all input
00979 BufferedTransformation & TheBitBucket();
00980 
00981 //! interface for crypto material, such as public and private keys, and crypto parameters
00982 
00983 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CryptoMaterial : public NameValuePairs
00984 {
00985 public:
00986     //! exception thrown when invalid crypto material is detected
00987     class CRYPTOPP_DLL InvalidMaterial : public InvalidDataFormat
00988     {
00989     public:
00990         explicit InvalidMaterial(const std::string &s) : InvalidDataFormat(s) {}
00991     };
00992 
00993     //! assign values from source to this object
00994     /*! \note This function can be used to create a public key from a private key. */
00995     virtual void AssignFrom(const NameValuePairs &source) =0;
00996 
00997     //! check this object for errors
00998     /*! \param level denotes the level of thoroughness:
00999         0 - using this object won't cause a crash or exception (rng is ignored)
01000         1 - this object will probably function (encrypt, sign, etc.) correctly (but may not check for weak keys and such)
01001         2 - make sure this object will function correctly, and do reasonable security checks
01002         3 - do checks that may take a long time
01003         \return true if the tests pass */
01004     virtual bool Validate(RandomNumberGenerator &rng, unsigned int level) const =0;
01005 
01006     //! throws InvalidMaterial if this object fails Validate() test
01007     virtual void ThrowIfInvalid(RandomNumberGenerator &rng, unsigned int level) const
01008         {if (!Validate(rng, level)) throw InvalidMaterial("CryptoMaterial: this object contains invalid values");}
01009 
01010 //  virtual std::vector<std::string> GetSupportedFormats(bool includeSaveOnly=false, bool includeLoadOnly=false);
01011 
01012     //! save key into a BufferedTransformation
01013     virtual void Save(BufferedTransformation &bt) const
01014         {throw NotImplemented("CryptoMaterial: this object does not support saving");}
01015 
01016     //! load key from a BufferedTransformation
01017     /*! \throws KeyingErr if decode fails
01018         \note Generally does not check that the key is valid.
01019             Call ValidateKey() or ThrowIfInvalidKey() to check that. */
01020     virtual void Load(BufferedTransformation &bt)
01021         {throw NotImplemented("CryptoMaterial: this object does not support loading");}
01022 
01023     //! \return whether this object supports precomputation
01024     virtual bool SupportsPrecomputation() const {return false;}
01025     //! do precomputation
01026     /*! The exact semantics of Precompute() is varies, but
01027         typically it means calculate a table of n objects
01028         that can be used later to speed up computation. */
01029     virtual void Precompute(unsigned int n)
01030         {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");}
01031     //! retrieve previously saved precomputation
01032     virtual void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
01033         {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");}
01034     //! save precomputation for later use
01035     virtual void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
01036         {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");}
01037 
01038     // for internal library use
01039     void DoQuickSanityCheck() const {ThrowIfInvalid(NullRNG(), 0);}
01040 
01041 #ifdef __SUNPRO_CC
01042     // Sun Studio 11/CC 5.8 workaround: it generates incorrect code when casting to an empty virtual base class
01043     char m_sunCCworkaround;
01044 #endif
01045 };
01046 
01047 //! interface for generatable crypto material, such as private keys and crypto parameters
01048 
01049 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GeneratableCryptoMaterial : virtual public CryptoMaterial
01050 {
01051 public:
01052     //! generate a random key or crypto parameters
01053     /*! \throws KeyingErr if algorithm parameters are invalid, or if a key can't be generated
01054         (e.g., if this is a public key object) */
01055     virtual void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params = g_nullNameValuePairs)
01056         {throw NotImplemented("GeneratableCryptoMaterial: this object does not support key/parameter generation");}
01057 
01058     //! calls the above function with a NameValuePairs object that just specifies "KeySize"
01059     void GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize);
01060 };
01061 
01062 //! interface for public keys
01063 
01064 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PublicKey : virtual public CryptoMaterial
01065 {
01066 };
01067 
01068 //! interface for private keys
01069 
01070 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PrivateKey : public GeneratableCryptoMaterial
01071 {
01072 };
01073 
01074 //! interface for crypto prameters
01075 
01076 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CryptoParameters : public GeneratableCryptoMaterial
01077 {
01078 };
01079 
01080 //! interface for asymmetric algorithms
01081 
01082 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AsymmetricAlgorithm : public Algorithm
01083 {
01084 public:
01085     //! returns a reference to the crypto material used by this object
01086     virtual CryptoMaterial & AccessMaterial() =0;
01087     //! returns a const reference to the crypto material used by this object
01088     virtual const CryptoMaterial & GetMaterial() const =0;
01089 
01090     //! for backwards compatibility, calls AccessMaterial().Load(bt)
01091     void BERDecode(BufferedTransformation &bt)
01092         {AccessMaterial().Load(bt);}
01093     //! for backwards compatibility, calls GetMaterial().Save(bt)
01094     void DEREncode(BufferedTransformation &bt) const
01095         {GetMaterial().Save(bt);}
01096 };
01097 
01098 //! interface for asymmetric algorithms using public keys
01099 
01100 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PublicKeyAlgorithm : public AsymmetricAlgorithm
01101 {
01102 public:
01103     // VC60 workaround: no co-variant return type
01104     CryptoMaterial & AccessMaterial() {return AccessPublicKey();}
01105     const CryptoMaterial & GetMaterial() const {return GetPublicKey();}
01106 
01107     virtual PublicKey & AccessPublicKey() =0;
01108     virtual const PublicKey & GetPublicKey() const {return const_cast<PublicKeyAlgorithm *>(this)->AccessPublicKey();}
01109 };
01110 
01111 //! interface for asymmetric algorithms using private keys
01112 
01113 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PrivateKeyAlgorithm : public AsymmetricAlgorithm
01114 {
01115 public:
01116     CryptoMaterial & AccessMaterial() {return AccessPrivateKey();}
01117     const CryptoMaterial & GetMaterial() const {return GetPrivateKey();}
01118 
01119     virtual PrivateKey & AccessPrivateKey() =0;
01120     virtual const PrivateKey & GetPrivateKey() const {return const_cast<PrivateKeyAlgorithm *>(this)->AccessPrivateKey();}
01121 };
01122 
01123 //! interface for key agreement algorithms
01124 
01125 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE KeyAgreementAlgorithm : public AsymmetricAlgorithm
01126 {
01127 public:
01128     CryptoMaterial & AccessMaterial() {return AccessCryptoParameters();}
01129     const CryptoMaterial & GetMaterial() const {return GetCryptoParameters();}
01130 
01131     virtual CryptoParameters & AccessCryptoParameters() =0;
01132     virtual const CryptoParameters & GetCryptoParameters() const {return const_cast<KeyAgreementAlgorithm *>(this)->AccessCryptoParameters();}
01133 };
01134 
01135 //! interface for public-key encryptors and decryptors
01136 
01137 /*! This class provides an interface common to encryptors and decryptors
01138     for querying their plaintext and ciphertext lengths.
01139 */
01140 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_CryptoSystem
01141 {
01142 public:
01143     virtual ~PK_CryptoSystem() {}
01144 
01145     //! maximum length of plaintext for a given ciphertext length
01146     /*! \note This function returns 0 if ciphertextLength is not valid (too long or too short). */
01147     virtual size_t MaxPlaintextLength(size_t ciphertextLength) const =0;
01148 
01149     //! calculate length of ciphertext given length of plaintext
01150     /*! \note This function returns 0 if plaintextLength is not valid (too long). */
01151     virtual size_t CiphertextLength(size_t plaintextLength) const =0;
01152 
01153     //! this object supports the use of the parameter with the given name
01154     /*! some possible parameter names: EncodingParameters, KeyDerivationParameters */
01155     virtual bool ParameterSupported(const char *name) const =0;
01156 
01157     //! return fixed ciphertext length, if one exists, otherwise return 0
01158     /*! \note "Fixed" here means length of ciphertext does not depend on length of plaintext.
01159         It usually does depend on the key length. */
01160     virtual size_t FixedCiphertextLength() const {return 0;}
01161 
01162     //! return maximum plaintext length given the fixed ciphertext length, if one exists, otherwise return 0
01163     virtual size_t FixedMaxPlaintextLength() const {return 0;}
01164 
01165 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
01166     size_t MaxPlainTextLength(size_t cipherTextLength) const {return MaxPlaintextLength(cipherTextLength);}
01167     size_t CipherTextLength(size_t plainTextLength) const {return CiphertextLength(plainTextLength);}
01168 #endif
01169 };
01170 
01171 //! interface for public-key encryptors
01172 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Encryptor : public PK_CryptoSystem, public PublicKeyAlgorithm
01173 {
01174 public:
01175     //! exception thrown when trying to encrypt plaintext of invalid length
01176     class CRYPTOPP_DLL InvalidPlaintextLength : public Exception
01177     {
01178     public:
01179         InvalidPlaintextLength() : Exception(OTHER_ERROR, "PK_Encryptor: invalid plaintext length") {}
01180     };
01181 
01182     //! encrypt a byte string
01183     /*! \pre CiphertextLength(plaintextLength) != 0 (i.e., plaintext isn't too long)
01184         \pre size of ciphertext == CiphertextLength(plaintextLength)
01185     */
01186     virtual void Encrypt(RandomNumberGenerator &rng, 
01187         const byte *plaintext, size_t plaintextLength, 
01188         byte *ciphertext, const NameValuePairs &parameters = g_nullNameValuePairs) const =0;
01189 
01190     //! create a new encryption filter
01191     /*! \note The caller is responsible for deleting the returned pointer.
01192         \note Encoding parameters should be passed in the "EP" channel.
01193     */
01194     virtual BufferedTransformation * CreateEncryptionFilter(RandomNumberGenerator &rng, 
01195         BufferedTransformation *attachment=NULL, const NameValuePairs &parameters = g_nullNameValuePairs) const;
01196 };
01197 
01198 //! interface for public-key decryptors
01199 
01200 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Decryptor : public PK_CryptoSystem, public PrivateKeyAlgorithm
01201 {
01202 public:
01203     //! decrypt a byte string, and return the length of plaintext
01204     /*! \pre size of plaintext == MaxPlaintextLength(ciphertextLength) bytes.
01205         \return the actual length of the plaintext, indication that decryption failed.
01206     */
01207     virtual DecodingResult Decrypt(RandomNumberGenerator &rng, 
01208         const byte *ciphertext, size_t ciphertextLength, 
01209         byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const =0;
01210 
01211     //! create a new decryption filter
01212     /*! \note caller is responsible for deleting the returned pointer
01213     */
01214     virtual BufferedTransformation * CreateDecryptionFilter(RandomNumberGenerator &rng, 
01215         BufferedTransformation *attachment=NULL, const NameValuePairs &parameters = g_nullNameValuePairs) const;
01216 
01217     //! decrypt a fixed size ciphertext
01218     DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *ciphertext, byte *plaintext, const NameValuePairs &parameters = g_nullNameValuePairs) const
01219         {return Decrypt(rng, ciphertext, FixedCiphertextLength(), plaintext, parameters);}
01220 };
01221 
01222 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
01223 typedef PK_CryptoSystem PK_FixedLengthCryptoSystem;
01224 typedef PK_Encryptor PK_FixedLengthEncryptor;
01225 typedef PK_Decryptor PK_FixedLengthDecryptor;
01226 #endif
01227 
01228 //! interface for public-key signers and verifiers
01229 
01230 /*! This class provides an interface common to signers and verifiers
01231     for querying scheme properties.
01232 */
01233 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_SignatureScheme
01234 {
01235 public:
01236     //! invalid key exception, may be thrown by any function in this class if the private or public key has a length that can't be used
01237     class CRYPTOPP_DLL InvalidKeyLength : public Exception
01238     {
01239     public:
01240         InvalidKeyLength(const std::string &message) : Exception(OTHER_ERROR, message) {}
01241     };
01242 
01243     //! key too short exception, may be thrown by any function in this class if the private or public key is too short to sign or verify anything
01244     class CRYPTOPP_DLL KeyTooShort : public InvalidKeyLength
01245     {
01246     public:
01247         KeyTooShort() : InvalidKeyLength("PK_Signer: key too short for this signature scheme") {}
01248     };
01249 
01250     virtual ~PK_SignatureScheme() {}
01251 
01252     //! signature length if it only depends on the key, otherwise 0
01253     virtual size_t SignatureLength() const =0;
01254 
01255     //! maximum signature length produced for a given length of recoverable message part
01256     virtual size_t MaxSignatureLength(size_t recoverablePartLength = 0) const {return SignatureLength();}
01257 
01258     //! length of longest message that can be recovered, or 0 if this signature scheme does not support message recovery
01259     virtual size_t MaxRecoverableLength() const =0;
01260 
01261     //! length of longest message that can be recovered from a signature of given length, or 0 if this signature scheme does not support message recovery
01262     virtual size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const =0;
01263 
01264     //! requires a random number generator to sign
01265     /*! if this returns false, NullRNG() can be passed to functions that take RandomNumberGenerator & */
01266     virtual bool IsProbabilistic() const =0;
01267 
01268     //! whether or not a non-recoverable message part can be signed
01269     virtual bool AllowNonrecoverablePart() const =0;
01270 
01271     //! if this function returns true, during verification you must input the signature before the message, otherwise you can input it at anytime */
01272     virtual bool SignatureUpfront() const {return false;}
01273 
01274     //! whether you must input the recoverable part before the non-recoverable part during signing
01275     virtual bool RecoverablePartFirst() const =0;
01276 };
01277 
01278 //! interface for accumulating messages to be signed or verified
01279 /*! Only Update() should be called
01280     on this class. No other functions inherited from HashTransformation should be called.
01281 */
01282 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulator : public HashTransformation
01283 {
01284 public:
01285     //! should not be called on PK_MessageAccumulator
01286     unsigned int DigestSize() const
01287         {throw NotImplemented("PK_MessageAccumulator: DigestSize() should not be called");}
01288     //! should not be called on PK_MessageAccumulator
01289     void TruncatedFinal(byte *digest, size_t digestSize) 
01290         {throw NotImplemented("PK_MessageAccumulator: TruncatedFinal() should not be called");}
01291 };
01292 
01293 //! interface for public-key signers
01294 
01295 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Signer : public PK_SignatureScheme, public PrivateKeyAlgorithm
01296 {
01297 public:
01298     //! create a new HashTransformation to accumulate the message to be signed
01299     virtual PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const =0;
01300 
01301     virtual void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const =0;
01302 
01303     //! sign and delete messageAccumulator (even in case of exception thrown)
01304     /*! \pre size of signature == MaxSignatureLength()
01305         \return actual signature length
01306     */
01307     virtual size_t Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const;
01308 
01309     //! sign and restart messageAccumulator
01310     /*! \pre size of signature == MaxSignatureLength()
01311         \return actual signature length
01312     */
01313     virtual size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const =0;
01314 
01315     //! sign a message
01316     /*! \pre size of signature == MaxSignatureLength()
01317         \return actual signature length
01318     */
01319     virtual size_t SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const;
01320 
01321     //! sign a recoverable message
01322     /*! \pre size of signature == MaxSignatureLength(recoverableMessageLength)
01323         \return actual signature length
01324     */
01325     virtual size_t SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, size_t recoverableMessageLength, 
01326         const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, byte *signature) const;
01327 };
01328 
01329 //! interface for public-key signature verifiers
01330 /*! The Recover* functions throw NotImplemented if the signature scheme does not support
01331     message recovery.
01332     The Verify* functions throw InvalidDataFormat if the scheme does support message
01333     recovery and the signature contains a non-empty recoverable message part. The
01334     Recovery* functions should be used in that case.
01335 */
01336 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Verifier : public PK_SignatureScheme, public PublicKeyAlgorithm
01337 {
01338 public:
01339     //! create a new HashTransformation to accumulate the message to be verified
01340     virtual PK_MessageAccumulator * NewVerificationAccumulator() const =0;
01341 
01342     //! input signature into a message accumulator
01343     virtual void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const =0;
01344 
01345     //! check whether messageAccumulator contains a valid signature and message, and delete messageAccumulator (even in case of exception thrown)
01346     virtual bool Verify(PK_MessageAccumulator *messageAccumulator) const;
01347 
01348     //! check whether messageAccumulator contains a valid signature and message, and restart messageAccumulator
01349     virtual bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const =0;
01350 
01351     //! check whether input signature is a valid signature for input message
01352     virtual bool VerifyMessage(const byte *message, size_t messageLen, 
01353         const byte *signature, size_t signatureLength) const;
01354 
01355     //! recover a message from its signature
01356     /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)
01357     */
01358     virtual DecodingResult Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const;
01359 
01360     //! recover a message from its signature
01361     /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)
01362     */
01363     virtual DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const =0;
01364 
01365     //! recover a message from its signature
01366     /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)
01367     */
01368     virtual DecodingResult RecoverMessage(byte *recoveredMessage, 
01369         const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, 
01370         const byte *signature, size_t signatureLength) const;
01371 };
01372 
01373 //! interface for domains of simple key agreement protocols
01374 
01375 /*! A key agreement domain is a set of parameters that must be shared
01376     by two parties in a key agreement protocol, along with the algorithms
01377     for generating key pairs and deriving agreed values.
01378 */
01379 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyAgreementDomain : public KeyAgreementAlgorithm
01380 {
01381 public:
01382     //! return length of agreed value produced
01383     virtual unsigned int AgreedValueLength() const =0;
01384     //! return length of private keys in this domain
01385     virtual unsigned int PrivateKeyLength() const =0;
01386     //! return length of public keys in this domain
01387     virtual unsigned int PublicKeyLength() const =0;
01388     //! generate private key
01389     /*! \pre size of privateKey == PrivateKeyLength() */
01390     virtual void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0;
01391     //! generate public key
01392     /*! \pre size of publicKey == PublicKeyLength() */
01393     virtual void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0;
01394     //! generate private/public key pair
01395     /*! \note equivalent to calling GeneratePrivateKey() and then GeneratePublicKey() */
01396     virtual void GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const;
01397     //! derive agreed value from your private key and couterparty's public key, return false in case of failure
01398     /*! \note If you have previously validated the public key, use validateOtherPublicKey=false to save time.
01399         \pre size of agreedValue == AgreedValueLength()
01400         \pre length of privateKey == PrivateKeyLength()
01401         \pre length of otherPublicKey == PublicKeyLength()
01402     */
01403     virtual bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const =0;
01404 
01405 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
01406     bool ValidateDomainParameters(RandomNumberGenerator &rng) const
01407         {return GetCryptoParameters().Validate(rng, 2);}
01408 #endif
01409 };
01410 
01411 //! interface for domains of authenticated key agreement protocols
01412 
01413 /*! In an authenticated key agreement protocol, each party has two
01414     key pairs. The long-lived key pair is called the static key pair,
01415     and the short-lived key pair is called the ephemeral key pair.
01416 */
01417 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AuthenticatedKeyAgreementDomain : public KeyAgreementAlgorithm
01418 {
01419 public:
01420     //! return length of agreed value produced
01421     virtual unsigned int AgreedValueLength() const =0;
01422 
01423     //! return length of static private keys in this domain
01424     virtual unsigned int StaticPrivateKeyLength() const =0;
01425     //! return length of static public keys in this domain
01426     virtual unsigned int StaticPublicKeyLength() const =0;
01427     //! generate static private key
01428     /*! \pre size of privateKey == PrivateStaticKeyLength() */
01429     virtual void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0;
01430     //! generate static public key
01431     /*! \pre size of publicKey == PublicStaticKeyLength() */
01432     virtual void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0;
01433     //! generate private/public key pair
01434     /*! \note equivalent to calling GenerateStaticPrivateKey() and then GenerateStaticPublicKey() */
01435     virtual void GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const;
01436 
01437     //! return length of ephemeral private keys in this domain
01438     virtual unsigned int EphemeralPrivateKeyLength() const =0;
01439     //! return length of ephemeral public keys in this domain
01440     virtual unsigned int EphemeralPublicKeyLength() const =0;
01441     //! generate ephemeral private key
01442     /*! \pre size of privateKey == PrivateEphemeralKeyLength() */
01443     virtual void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0;
01444     //! generate ephemeral public key
01445     /*! \pre size of publicKey == PublicEphemeralKeyLength() */
01446     virtual void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0;
01447     //! generate private/public key pair
01448     /*! \note equivalent to calling GenerateEphemeralPrivateKey() and then GenerateEphemeralPublicKey() */
01449     virtual void GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const;
01450 
01451     //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure
01452     /*! \note The ephemeral public key will always be validated.
01453               If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time.
01454         \pre size of agreedValue == AgreedValueLength()
01455         \pre length of staticPrivateKey == StaticPrivateKeyLength()
01456         \pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength()
01457         \pre length of staticOtherPublicKey == StaticPublicKeyLength()
01458         \pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength()
01459     */
01460     virtual bool Agree(byte *agreedValue,
01461         const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
01462         const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
01463         bool validateStaticOtherPublicKey=true) const =0;
01464 
01465 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
01466     bool ValidateDomainParameters(RandomNumberGenerator &rng) const
01467         {return GetCryptoParameters().Validate(rng, 2);}
01468 #endif
01469 };
01470 
01471 // interface for password authenticated key agreement protocols, not implemented yet
01472 #if 0
01473 //! interface for protocol sessions
01474 /*! The methods should be called in the following order:
01475 
01476     InitializeSession(rng, parameters); // or call initialize method in derived class
01477     while (true)
01478     {
01479         if (OutgoingMessageAvailable())
01480         {
01481             length = GetOutgoingMessageLength();
01482             GetOutgoingMessage(message);
01483             ; // send outgoing message
01484         }
01485 
01486         if (LastMessageProcessed())
01487             break;
01488 
01489         ; // receive incoming message
01490         ProcessIncomingMessage(message);
01491     }
01492     ; // call methods in derived class to obtain result of protocol session
01493 */
01494 class ProtocolSession
01495 {
01496 public:
01497     //! exception thrown when an invalid protocol message is processed
01498     class ProtocolError : public Exception
01499     {
01500     public:
01501         ProtocolError(ErrorType errorType, const std::string &s) : Exception(errorType, s) {}
01502     };
01503 
01504     //! exception thrown when a function is called unexpectedly
01505     /*! for example calling ProcessIncomingMessage() when ProcessedLastMessage() == true */
01506     class UnexpectedMethodCall : public Exception
01507     {
01508     public:
01509         UnexpectedMethodCall(const std::string &s) : Exception(OTHER_ERROR, s) {}
01510     };
01511 
01512     ProtocolSession() : m_rng(NULL), m_throwOnProtocolError(true), m_validState(false) {}
01513     virtual ~ProtocolSession() {}
01514 
01515     virtual void InitializeSession(RandomNumberGenerator &rng, const NameValuePairs &parameters) =0;
01516 
01517     bool GetThrowOnProtocolError() const {return m_throwOnProtocolError;}
01518     void SetThrowOnProtocolError(bool throwOnProtocolError) {m_throwOnProtocolError = throwOnProtocolError;}
01519 
01520     bool HasValidState() const {return m_validState;}
01521 
01522     virtual bool OutgoingMessageAvailable() const =0;
01523     virtual unsigned int GetOutgoingMessageLength() const =0;
01524     virtual void GetOutgoingMessage(byte *message) =0;
01525 
01526     virtual bool LastMessageProcessed() const =0;
01527     virtual void ProcessIncomingMessage(const byte *message, unsigned int messageLength) =0;
01528 
01529 protected:
01530     void HandleProtocolError(Exception::ErrorType errorType, const std::string &s) const;
01531     void CheckAndHandleInvalidState() const;
01532     void SetValidState(bool valid) {m_validState = valid;}
01533 
01534     RandomNumberGenerator *m_rng;
01535 
01536 private:
01537     bool m_throwOnProtocolError, m_validState;
01538 };
01539 
01540 class KeyAgreementSession : public ProtocolSession
01541 {
01542 public:
01543     virtual unsigned int GetAgreedValueLength() const =0;
01544     virtual void GetAgreedValue(byte *agreedValue) const =0;
01545 };
01546 
01547 class PasswordAuthenticatedKeyAgreementSession : public KeyAgreementSession
01548 {
01549 public:
01550     void InitializePasswordAuthenticatedKeyAgreementSession(RandomNumberGenerator &rng, 
01551         const byte *myId, unsigned int myIdLength, 
01552         const byte *counterPartyId, unsigned int counterPartyIdLength, 
01553         const byte *passwordOrVerifier, unsigned int passwordOrVerifierLength);
01554 };
01555 
01556 class PasswordAuthenticatedKeyAgreementDomain : public KeyAgreementAlgorithm
01557 {
01558 public:
01559     //! return whether the domain parameters stored in this object are valid
01560     virtual bool ValidateDomainParameters(RandomNumberGenerator &rng) const
01561         {return GetCryptoParameters().Validate(rng, 2);}
01562 
01563     virtual unsigned int GetPasswordVerifierLength(const byte *password, unsigned int passwordLength) const =0;
01564     virtual void GeneratePasswordVerifier(RandomNumberGenerator &rng, const byte *userId, unsigned int userIdLength, const byte *password, unsigned int passwordLength, byte *verifier) const =0;
01565 
01566     enum RoleFlags {CLIENT=1, SERVER=2, INITIATOR=4, RESPONDER=8};
01567 
01568     virtual bool IsValidRole(unsigned int role) =0;
01569     virtual PasswordAuthenticatedKeyAgreementSession * CreateProtocolSession(unsigned int role) const =0;
01570 };
01571 #endif
01572 
01573 //! BER Decode Exception Class, may be thrown during an ASN1 BER decode operation
01574 class CRYPTOPP_DLL BERDecodeErr : public InvalidArgument
01575 {
01576 public: 
01577     BERDecodeErr() : InvalidArgument("BER decode error") {}
01578     BERDecodeErr(const std::string &s) : InvalidArgument(s) {}
01579 };
01580 
01581 //! interface for encoding and decoding ASN1 objects
01582 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ASN1Object
01583 {
01584 public:
01585     virtual ~ASN1Object() {}
01586     //! decode this object from a BufferedTransformation, using BER (Basic Encoding Rules)
01587     virtual void BERDecode(BufferedTransformation &bt) =0;
01588     //! encode this object into a BufferedTransformation, using DER (Distinguished Encoding Rules)
01589     virtual void DEREncode(BufferedTransformation &bt) const =0;
01590     //! encode this object into a BufferedTransformation, using BER
01591     /*! this may be useful if DEREncode() would be too inefficient */
01592     virtual void BEREncode(BufferedTransformation &bt) const {DEREncode(bt);}
01593 };
01594 
01595 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
01596 typedef PK_SignatureScheme PK_SignatureSystem;
01597 typedef SimpleKeyAgreementDomain PK_SimpleKeyAgreementDomain;
01598 typedef AuthenticatedKeyAgreementDomain PK_AuthenticatedKeyAgreementDomain;
01599 #endif
01600 
01601 NAMESPACE_END
01602 
01603 #endif

Generated on Thu Jul 5 22:21:36 2007 for Crypto++ by  doxygen 1.5.2