Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

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

Generated on Tue Aug 16 08:38:40 2005 for Crypto++ by  doxygen 1.3.9.1