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

Generated on Sun Sep 16 18:29:51 2007 for Crypto++ by  doxygen 1.5.3