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