Crypto++
|
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 ¶ms = 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 ¶ms) =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 ¶ms, 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 ¶meters) {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 ¶meters=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 ¶ms = 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 ¶meters = 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 ¶meters = 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 ¶meters = 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 ¶meters = g_nullNameValuePairs) const; 01267 01268 //! decrypt a fixed size ciphertext 01269 DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *ciphertext, byte *plaintext, const NameValuePairs ¶meters = 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 ¶meters) =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