Crypto++

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

cryptlib.h
Go to the documentation of this file.

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