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

Generated on Mon Aug 9 2010 15:56:33 for Crypto++ by  doxygen 1.7.1