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