1// cryptlib.h - written and placed in the public domain by Wei Dai 2/*! \file 3 This file contains the declarations for the abstract base 4 classes that provide a uniform interface to this library. 5*/ 6 7/*! \mainpage Crypto++ Library 5.6.0 API Reference 8<dl> 9<dt>Abstract Base Classes<dd> 10 cryptlib.h 11<dt>Authenticated Encryption<dd> 12 AuthenticatedSymmetricCipherDocumentation 13<dt>Symmetric Ciphers<dd> 14 SymmetricCipherDocumentation 15<dt>Hash Functions<dd> 16 SHA1, SHA224, SHA256, SHA384, SHA512, Tiger, Whirlpool, RIPEMD160, RIPEMD320, RIPEMD128, RIPEMD256, Weak1::MD2, Weak1::MD4, Weak1::MD5 17<dt>Non-Cryptographic Checksums<dd> 18 CRC32, Adler32 19<dt>Message Authentication Codes<dd> 20 VMAC, HMAC, CBC_MAC, CMAC, DMAC, TTMAC, GCM (GMAC) 21<dt>Random Number Generators<dd> 22 NullRNG(), LC_RNG, RandomPool, BlockingRng, NonblockingRng, AutoSeededRandomPool, AutoSeededX917RNG, DefaultAutoSeededRNG 23<dt>Password-based Cryptography<dd> 24 PasswordBasedKeyDerivationFunction 25<dt>Public Key Cryptosystems<dd> 26 DLIES, ECIES, LUCES, RSAES, RabinES, LUC_IES 27<dt>Public Key Signature Schemes<dd> 28 DSA, GDSA, ECDSA, NR, ECNR, LUCSS, RSASS, RSASS_ISO, RabinSS, RWSS, ESIGN 29<dt>Key Agreement<dd> 30 #DH, DH2, #MQV, ECDH, ECMQV, XTR_DH 31<dt>Algebraic Structures<dd> 32 Integer, PolynomialMod2, PolynomialOver, RingOfPolynomialsOver, 33 ModularArithmetic, MontgomeryRepresentation, GFP2_ONB, 34 GF2NP, GF256, GF2_32, EC2N, ECP 35<dt>Secret Sharing and Information Dispersal<dd> 36 SecretSharing, SecretRecovery, InformationDispersal, InformationRecovery 37<dt>Compression<dd> 38 Deflator, Inflator, Gzip, Gunzip, ZlibCompressor, ZlibDecompressor 39<dt>Input Source Classes<dd> 40 StringSource, ArraySource, FileSource, SocketSource, WindowsPipeSource, RandomNumberSource 41<dt>Output Sink Classes<dd> 42 StringSinkTemplate, ArraySink, FileSink, SocketSink, WindowsPipeSink, RandomNumberSink 43<dt>Filter Wrappers<dd> 44 StreamTransformationFilter, HashFilter, HashVerificationFilter, SignerFilter, SignatureVerificationFilter 45<dt>Binary to Text Encoders and Decoders<dd> 46 HexEncoder, HexDecoder, Base64Encoder, Base64Decoder, Base32Encoder, Base32Decoder 47<dt>Wrappers for OS features<dd> 48 Timer, Socket, WindowsHandle, ThreadLocalStorage, ThreadUserTimer 49<dt>FIPS 140 related<dd> 50 fips140.h 51</dl> 52 53In the FIPS 140-2 validated DLL version of Crypto++, only the following implementation class are available. 54<dl> 55<dt>Block Ciphers<dd> 56 AES, DES_EDE2, DES_EDE3, SKIPJACK 57<dt>Cipher Modes (replace template parameter BC with one of the block ciphers above)<dd> 58 ECB_Mode\<BC\>, CTR_Mode\<BC\>, CBC_Mode\<BC\>, CFB_FIPS_Mode\<BC\>, OFB_Mode\<BC\> 59<dt>Hash Functions<dd> 60 SHA1, SHA224, SHA256, SHA384, SHA512 61<dt>Public Key Signature Schemes (replace template parameter H with one of the hash functions above)<dd> 62 RSASS\<PKCS1v15, H\>, RSASS\<PSS, H\>, RSASS_ISO\<H\>, RWSS\<P1363_EMSA2, H\>, DSA, ECDSA\<ECP, H\>, ECDSA\<EC2N, H\> 63<dt>Message Authentication Codes (replace template parameter H with one of the hash functions above)<dd> 64 HMAC\<H\>, CBC_MAC\<DES_EDE2\>, CBC_MAC\<DES_EDE3\> 65<dt>Random Number Generators<dd> 66 DefaultAutoSeededRNG (AutoSeededX917RNG\<AES\>) 67<dt>Key Agreement<dd> 68 #DH 69<dt>Public Key Cryptosystems<dd> 70 RSAES\<OAEP\<SHA1\> \> 71</dl> 72 73<p>This reference manual is a work in progress. Some classes are still lacking detailed descriptions. 74<p>Click <a href="CryptoPPRef.zip">here</a> to download a zip archive containing this manual. 75<p>Thanks to Ryan Phillips for providing the Doxygen configuration file 76and getting me started with this manual. 77*/ 78 79#ifndef CRYPTOPP_CRYPTLIB_H 80#define CRYPTOPP_CRYPTLIB_H 81 82#include "config.h" 83#include "stdcpp.h" 84 85NAMESPACE_BEGIN(CryptoPP) 86 87// forward declarations 88class Integer; 89class RandomNumberGenerator; 90class BufferedTransformation; 91 92//! used to specify a direction for a cipher to operate in (encrypt or decrypt) 93enum CipherDir {ENCRYPTION, DECRYPTION}; 94 95//! used to represent infinite time 96const unsigned long INFINITE_TIME = ULONG_MAX; 97 98// VC60 workaround: using enums as template parameters causes problems 99template <typename ENUM_TYPE, int VALUE> 100struct EnumToType 101{ 102 static ENUM_TYPE ToEnum() {return (ENUM_TYPE)VALUE;} 103}; 104 105enum ByteOrder {LITTLE_ENDIAN_ORDER = 0, BIG_ENDIAN_ORDER = 1}; 106typedef EnumToType<ByteOrder, LITTLE_ENDIAN_ORDER> LittleEndian; 107typedef EnumToType<ByteOrder, BIG_ENDIAN_ORDER> BigEndian; 108 109//! base class for all exceptions thrown by Crypto++ 110class CRYPTOPP_DLL Exception : public std::exception 111{ 112public: 113 //! error types 114 enum ErrorType { 115 //! a method is not implemented 116 NOT_IMPLEMENTED, 117 //! invalid function argument 118 INVALID_ARGUMENT, 119 //! BufferedTransformation received a Flush(true) signal but can't flush buffers 120 CANNOT_FLUSH, 121 //! data integerity check (such as CRC or MAC) failed 122 DATA_INTEGRITY_CHECK_FAILED, 123 //! received input data that doesn't conform to expected format 124 INVALID_DATA_FORMAT, 125 //! error reading from input device or writing to output device 126 IO_ERROR, 127 //! some error not belong to any of the above categories 128 OTHER_ERROR 129 }; 130 131 explicit Exception(ErrorType errorType, const std::string &s) : m_errorType(errorType), m_what(s) {} 132 virtual ~Exception() throw() {} 133 const char *what() const throw() {return (m_what.c_str());} 134 const std::string &GetWhat() const {return m_what;} 135 void SetWhat(const std::string &s) {m_what = s;} 136 ErrorType GetErrorType() const {return m_errorType;} 137 void SetErrorType(ErrorType errorType) {m_errorType = errorType;} 138 139private: 140 ErrorType m_errorType; 141 std::string m_what; 142}; 143 144//! exception thrown when an invalid argument is detected 145class CRYPTOPP_DLL InvalidArgument : public Exception 146{ 147public: 148 explicit InvalidArgument(const std::string &s) : Exception(INVALID_ARGUMENT, s) {} 149}; 150 151//! exception thrown when input data is received that doesn't conform to expected format 152class CRYPTOPP_DLL InvalidDataFormat : public Exception 153{ 154public: 155 explicit InvalidDataFormat(const std::string &s) : Exception(INVALID_DATA_FORMAT, s) {} 156}; 157 158//! exception thrown by decryption filters when trying to decrypt an invalid ciphertext 159class CRYPTOPP_DLL InvalidCiphertext : public InvalidDataFormat 160{ 161public: 162 explicit InvalidCiphertext(const std::string &s) : InvalidDataFormat(s) {} 163}; 164 165//! exception thrown by a class if a non-implemented method is called 166class CRYPTOPP_DLL NotImplemented : public Exception 167{ 168public: 169 explicit NotImplemented(const std::string &s) : Exception(NOT_IMPLEMENTED, s) {} 170}; 171 172//! exception thrown by a class when Flush(true) is called but it can't completely flush its buffers 173class CRYPTOPP_DLL CannotFlush : public Exception 174{ 175public: 176 explicit CannotFlush(const std::string &s) : Exception(CANNOT_FLUSH, s) {} 177}; 178 179//! error reported by the operating system 180class CRYPTOPP_DLL OS_Error : public Exception 181{ 182public: 183 OS_Error(ErrorType errorType, const std::string &s, const std::string& operation, int errorCode) 184 : Exception(errorType, s), m_operation(operation), m_errorCode(errorCode) {} 185 ~OS_Error() throw() {} 186 187 // the operating system API that reported the error 188 const std::string & GetOperation() const {return m_operation;} 189 // the error code return by the operating system 190 int GetErrorCode() const {return m_errorCode;} 191 192protected: 193 std::string m_operation; 194 int m_errorCode; 195}; 196 197//! used to return decoding results 198struct CRYPTOPP_DLL DecodingResult 199{ 200 explicit DecodingResult() : isValidCoding(false), messageLength(0) {} 201 explicit DecodingResult(size_t len) : isValidCoding(true), messageLength(len) {} 202 203 bool operator==(const DecodingResult &rhs) const {return isValidCoding == rhs.isValidCoding && messageLength == rhs.messageLength;} 204 bool operator!=(const DecodingResult &rhs) const {return !operator==(rhs);} 205 206 bool isValidCoding; 207 size_t messageLength; 208 209#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY 210 operator size_t() const {return isValidCoding ? messageLength : 0;} 211#endif 212}; 213 214//! interface for retrieving values given their names 215/*! \note This class is used to safely pass a variable number of arbitrarily typed arguments to functions 216 and to read values from keys and crypto parameters. 217 \note To obtain an object that implements NameValuePairs for the purpose of parameter 218 passing, use the MakeParameters() function. 219 \note To get a value from NameValuePairs, you need to know the name and the type of the value. 220 Call GetValueNames() on a NameValuePairs object to obtain a list of value names that it supports. 221 Then look at the Name namespace documentation to see what the type of each value is, or 222 alternatively, call GetIntValue() with the value name, and if the type is not int, a 223 ValueTypeMismatch exception will be thrown and you can get the actual type from the exception object. 224*/ 225class CRYPTOPP_NO_VTABLE NameValuePairs 226{ 227public: 228 virtual ~NameValuePairs() {} 229 230 //! exception thrown when trying to retrieve a value using a different type than expected 231 class CRYPTOPP_DLL ValueTypeMismatch : public InvalidArgument 232 { 233 public: 234 ValueTypeMismatch(const std::string &name, const std::type_info &stored, const std::type_info &retrieving) 235 : InvalidArgument("NameValuePairs: type mismatch for '" + name + "', stored '" + stored.name() + "', trying to retrieve '" + retrieving.name() + "'") 236 , m_stored(stored), m_retrieving(retrieving) {} 237 238 const std::type_info & GetStoredTypeInfo() const {return m_stored;} 239 const std::type_info & GetRetrievingTypeInfo() const {return m_retrieving;} 240 241 private: 242 const std::type_info &m_stored; 243 const std::type_info &m_retrieving; 244 }; 245 246 //! get a copy of this object or a subobject of it 247 template <class T> 248 bool GetThisObject(T &object) const 249 { 250 return GetValue((std::string("ThisObject:")+typeid(T).name()).c_str(), object); 251 } 252 253 //! get a pointer to this object, as a pointer to T 254 template <class T> 255 bool GetThisPointer(T *&p) const 256 { 257 return GetValue((std::string("ThisPointer:")+typeid(T).name()).c_str(), p); 258 } 259 260 //! get a named value, returns true if the name exists 261 template <class T> 262 bool GetValue(const char *name, T &value) const 263 { 264 return GetVoidValue(name, typeid(T), &value); 265 } 266 267 //! get a named value, returns the default if the name doesn't exist 268 template <class T> 269 T GetValueWithDefault(const char *name, T defaultValue) const 270 { 271 GetValue(name, defaultValue); 272 return defaultValue; 273 } 274 275 //! get a list of value names that can be retrieved 276 CRYPTOPP_DLL std::string GetValueNames() const 277 {std::string result; GetValue("ValueNames", result); return result;} 278 279 //! get a named value with type int 280 /*! used to ensure we don't accidentally try to get an unsigned int 281 or some other type when we mean int (which is the most common case) */ 282 CRYPTOPP_DLL bool GetIntValue(const char *name, int &value) const 283 {return GetValue(name, value);} 284 285 //! get a named value with type int, with default 286 CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const 287 {return GetValueWithDefault(name, defaultValue);} 288 289 //! used by derived classes to check for type mismatch 290 CRYPTOPP_DLL static void CRYPTOPP_API ThrowIfTypeMismatch(const char *name, const std::type_info &stored, const std::type_info &retrieving) 291 {if (stored != retrieving) throw ValueTypeMismatch(name, stored, retrieving);} 292 293 template <class T> 294 void GetRequiredParameter(const char *className, const char *name, T &value) const 295 { 296 if (!GetValue(name, value)) 297 throw InvalidArgument(std::string(className) + ": missing required parameter '" + name + "'"); 298 } 299 300 CRYPTOPP_DLL void GetRequiredIntParameter(const char *className, const char *name, int &value) const 301 { 302 if (!GetIntValue(name, value)) 303 throw InvalidArgument(std::string(className) + ": missing required parameter '" + name + "'"); 304 } 305 306 //! to be implemented by derived classes, users should use one of the above functions instead 307 CRYPTOPP_DLL virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const =0; 308}; 309 310//! namespace containing value name definitions 311/*! value names, types and semantics: 312 313 ThisObject:ClassName (ClassName, copy of this object or a subobject) 314 ThisPointer:ClassName (const ClassName *, pointer to this object or a subobject) 315*/ 316DOCUMENTED_NAMESPACE_BEGIN(Name) 317// more names defined in argnames.h 318DOCUMENTED_NAMESPACE_END 319 320//! empty set of name-value pairs 321class CRYPTOPP_DLL NullNameValuePairs : public NameValuePairs 322{ 323public: 324 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const {return false;} 325}; 326 327//! _ 328extern CRYPTOPP_DLL const NullNameValuePairs g_nullNameValuePairs; 329 330// ******************************************************** 331 332//! interface for cloning objects, this is not implemented by most classes yet 333class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Clonable 334{ 335public: 336 virtual ~Clonable() {} 337 //! this is not implemented by most classes yet 338 virtual Clonable* Clone() const {throw NotImplemented("Clone() is not implemented yet.");} // TODO: make this =0 339}; 340 341//! interface for all crypto algorithms 342 343class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Algorithm : public Clonable 344{ 345public: 346 /*! When FIPS 140-2 compliance is enabled and checkSelfTestStatus == true, 347 this constructor throws SelfTestFailure if the self test hasn't been run or fails. */ 348 Algorithm(bool checkSelfTestStatus = true); 349 //! returns name of this algorithm, not universally implemented yet 350 virtual std::string AlgorithmName() const {return "unknown";} 351}; 352 353//! keying interface for crypto algorithms that take byte strings as keys 354class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyingInterface 355{ 356public: 357 virtual ~SimpleKeyingInterface() {} 358 359 //! returns smallest valid key length in bytes */ 360 virtual size_t MinKeyLength() const =0; 361 //! returns largest valid key length in bytes */ 362 virtual size_t MaxKeyLength() const =0; 363 //! returns default (recommended) key length in bytes */ 364 virtual size_t DefaultKeyLength() const =0; 365 366 //! returns the smallest valid key length in bytes that is >= min(n, GetMaxKeyLength()) 367 virtual size_t GetValidKeyLength(size_t n) const =0; 368 369 //! returns whether n is a valid key length 370 virtual bool IsValidKeyLength(size_t n) const 371 {return n == GetValidKeyLength(n);} 372 373 //! set or reset the key of this object 374 /*! \param params is used to specify Rounds, BlockSize, etc. */ 375 virtual void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms = g_nullNameValuePairs); 376 377 //! calls SetKey() with an NameValuePairs object that just specifies "Rounds" 378 void SetKeyWithRounds(const byte *key, size_t length, int rounds); 379 380 //! calls SetKey() with an NameValuePairs object that just specifies "IV" 381 void SetKeyWithIV(const byte *key, size_t length, const byte *iv, size_t ivLength); 382 383 //! calls SetKey() with an NameValuePairs object that just specifies "IV" 384 void SetKeyWithIV(const byte *key, size_t length, const byte *iv) 385 {SetKeyWithIV(key, length, iv, IVSize());} 386 387 enum IV_Requirement {UNIQUE_IV = 0, RANDOM_IV, UNPREDICTABLE_RANDOM_IV, INTERNALLY_GENERATED_IV, NOT_RESYNCHRONIZABLE}; 388 //! returns the minimal requirement for secure IVs 389 virtual IV_Requirement IVRequirement() const =0; 390 391 //! returns whether this object can be resynchronized (i.e. supports initialization vectors) 392 /*! If this function returns true, and no IV is passed to SetKey() and CanUseStructuredIVs()==true, an IV of all 0's will be assumed. */ 393 bool IsResynchronizable() const {return IVRequirement() < NOT_RESYNCHRONIZABLE;} 394 //! returns whether this object can use random IVs (in addition to ones returned by GetNextIV) 395 bool CanUseRandomIVs() const {return IVRequirement() <= UNPREDICTABLE_RANDOM_IV;} 396 //! returns whether this object can use random but possibly predictable IVs (in addition to ones returned by GetNextIV) 397 bool CanUsePredictableIVs() const {return IVRequirement() <= RANDOM_IV;} 398 //! returns whether this object can use structured IVs, for example a counter (in addition to ones returned by GetNextIV) 399 bool CanUseStructuredIVs() const {return IVRequirement() <= UNIQUE_IV;} 400 401 virtual unsigned int IVSize() const {throw NotImplemented(GetAlgorithm().AlgorithmName() + ": this object doesn't support resynchronization");} 402 //! returns default length of IVs accepted by this object 403 unsigned int DefaultIVLength() const {return IVSize();} 404 //! returns minimal length of IVs accepted by this object 405 virtual unsigned int MinIVLength() const {return IVSize();} 406 //! returns maximal length of IVs accepted by this object 407 virtual unsigned int MaxIVLength() const {return IVSize();} 408 //! resynchronize with an IV. ivLength=-1 means use IVSize() 409 virtual void Resynchronize(const byte *iv, int ivLength=-1) {throw NotImplemented(GetAlgorithm().AlgorithmName() + ": this object doesn't support resynchronization");} 410 //! get a secure IV for the next message 411 /*! This method should be called after you finish encrypting one message and are ready to start the next one. 412 After calling it, you must call SetKey() or Resynchronize() before using this object again. 413 This method is not implemented on decryption objects. */ 414 virtual void GetNextIV(RandomNumberGenerator &rng, byte *IV); 415 416protected: 417 virtual const Algorithm & GetAlgorithm() const =0; 418 virtual void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) =0; 419 420 void ThrowIfInvalidKeyLength(size_t length); 421 void ThrowIfResynchronizable(); // to be called when no IV is passed 422 void ThrowIfInvalidIV(const byte *iv); // check for NULL IV if it can't be used 423 size_t ThrowIfInvalidIVLength(int size); 424 const byte * GetIVAndThrowIfInvalid(const NameValuePairs ¶ms, size_t &size); 425 inline void AssertValidKeyLength(size_t length) const 426 {assert(IsValidKeyLength(length));} 427}; 428 429//! interface for the data processing part of block ciphers 430 431/*! Classes derived from BlockTransformation are block ciphers 432 in ECB mode (for example the DES::Encryption class), which are stateless. 433 These classes should not be used directly, but only in combination with 434 a mode class (see CipherModeDocumentation in modes.h). 435*/ 436class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockTransformation : public Algorithm 437{ 438public: 439 //! encrypt or decrypt inBlock, xor with xorBlock, and write to outBlock 440 virtual void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const =0; 441 442 //! encrypt or decrypt one block 443 /*! \pre size of inBlock and outBlock == BlockSize() */ 444 void ProcessBlock(const byte *inBlock, byte *outBlock) const 445 {ProcessAndXorBlock(inBlock, NULL, outBlock);} 446 447 //! encrypt or decrypt one block in place 448 void ProcessBlock(byte *inoutBlock) const 449 {ProcessAndXorBlock(inoutBlock, NULL, inoutBlock);} 450 451 //! block size of the cipher in bytes 452 virtual unsigned int BlockSize() const =0; 453 454 //! returns how inputs and outputs should be aligned for optimal performance 455 virtual unsigned int OptimalDataAlignment() const; 456 457 //! returns true if this is a permutation (i.e. there is an inverse transformation) 458 virtual bool IsPermutation() const {return true;} 459 460 //! returns true if this is an encryption object 461 virtual bool IsForwardTransformation() const =0; 462 463 //! return number of blocks that can be processed in parallel, for bit-slicing implementations 464 virtual unsigned int OptimalNumberOfParallelBlocks() const {return 1;} 465 466 enum {BT_InBlockIsCounter=1, BT_DontIncrementInOutPointers=2, BT_XorInput=4, BT_ReverseDirection=8} FlagsForAdvancedProcessBlocks; 467 468 //! encrypt and xor blocks according to flags (see FlagsForAdvancedProcessBlocks) 469 /*! /note If BT_InBlockIsCounter is set, last byte of inBlocks may be modified. */ 470 virtual size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; 471 472 inline CipherDir GetCipherDirection() const {return IsForwardTransformation() ? ENCRYPTION : DECRYPTION;} 473}; 474 475//! interface for the data processing part of stream ciphers 476 477class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE StreamTransformation : public Algorithm 478{ 479public: 480 //! return a reference to this object, 481 /*! This function is useful for passing a temporary StreamTransformation object to a 482 function that takes a non-const reference. */ 483 StreamTransformation& Ref() {return *this;} 484 485 //! returns block size, if input must be processed in blocks, otherwise 1 486 virtual unsigned int MandatoryBlockSize() const {return 1;} 487 488 //! returns the input block size that is most efficient for this cipher 489 /*! \note optimal input length is n * OptimalBlockSize() - GetOptimalBlockSizeUsed() for any n > 0 */ 490 virtual unsigned int OptimalBlockSize() const {return MandatoryBlockSize();} 491 //! returns how much of the current block is used up 492 virtual unsigned int GetOptimalBlockSizeUsed() const {return 0;} 493 494 //! returns how input should be aligned for optimal performance 495 virtual unsigned int OptimalDataAlignment() const; 496 497 //! encrypt or decrypt an array of bytes of specified length 498 /*! \note either inString == outString, or they don't overlap */ 499 virtual void ProcessData(byte *outString, const byte *inString, size_t length) =0; 500 501 //! for ciphers where the last block of data is special, encrypt or decrypt the last block of data 502 /*! For now the only use of this function is for CBC-CTS mode. */ 503 virtual void ProcessLastBlock(byte *outString, const byte *inString, size_t length); 504 //! returns the minimum size of the last block, 0 indicating the last block is not special 505 virtual unsigned int MinLastBlockSize() const {return 0;} 506 507 //! same as ProcessData(inoutString, inoutString, length) 508 inline void ProcessString(byte *inoutString, size_t length) 509 {ProcessData(inoutString, inoutString, length);} 510 //! same as ProcessData(outString, inString, length) 511 inline void ProcessString(byte *outString, const byte *inString, size_t length) 512 {ProcessData(outString, inString, length);} 513 //! implemented as {ProcessData(&input, &input, 1); return input;} 514 inline byte ProcessByte(byte input) 515 {ProcessData(&input, &input, 1); return input;} 516 517 //! returns whether this cipher supports random access 518 virtual bool IsRandomAccess() const =0; 519 //! for random access ciphers, seek to an absolute position 520 virtual void Seek(lword n) 521 { 522 assert(!IsRandomAccess()); 523 throw NotImplemented("StreamTransformation: this object doesn't support random access"); 524 } 525 526 //! returns whether this transformation is self-inverting (e.g. xor with a keystream) 527 virtual bool IsSelfInverting() const =0; 528 //! returns whether this is an encryption object 529 virtual bool IsForwardTransformation() const =0; 530}; 531 532//! interface for hash functions and data processing part of MACs 533 534/*! HashTransformation objects are stateful. They are created in an initial state, 535 change state as Update() is called, and return to the initial 536 state when Final() is called. This interface allows a large message to 537 be hashed in pieces by calling Update() on each piece followed by 538 calling Final(). 539*/ 540class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE HashTransformation : public Algorithm 541{ 542public: 543 //! return a reference to this object, 544 /*! This function is useful for passing a temporary HashTransformation object to a 545 function that takes a non-const reference. */ 546 HashTransformation& Ref() {return *this;} 547 548 //! process more input 549 virtual void Update(const byte *input, size_t length) =0; 550 551 //! request space to write input into 552 virtual byte * CreateUpdateSpace(size_t &size) {size=0; return NULL;} 553 554 //! compute hash for current message, then restart for a new message 555 /*! \pre size of digest == DigestSize(). */ 556 virtual void Final(byte *digest) 557 {TruncatedFinal(digest, DigestSize());} 558 559 //! discard the current state, and restart with a new message 560 virtual void Restart() 561 {TruncatedFinal(NULL, 0);} 562 563 //! size of the hash/digest/MAC returned by Final() 564 virtual unsigned int DigestSize() const =0; 565 566 //! same as DigestSize() 567 unsigned int TagSize() const {return DigestSize();} 568 569 570 //! block size of underlying compression function, or 0 if not block based 571 virtual unsigned int BlockSize() const {return 0;} 572 573 //! input to Update() should have length a multiple of this for optimal speed 574 virtual unsigned int OptimalBlockSize() const {return 1;} 575 576 //! returns how input should be aligned for optimal performance 577 virtual unsigned int OptimalDataAlignment() const; 578 579 //! use this if your input is in one piece and you don't want to call Update() and Final() separately 580 virtual void CalculateDigest(byte *digest, const byte *input, size_t length) 581 {Update(input, length); Final(digest);} 582 583 //! verify that digest is a valid digest for the current message, then reinitialize the object 584 /*! Default implementation is to call Final() and do a bitwise comparison 585 between its output and digest. */ 586 virtual bool Verify(const byte *digest) 587 {return TruncatedVerify(digest, DigestSize());} 588 589 //! use this if your input is in one piece and you don't want to call Update() and Verify() separately 590 virtual bool VerifyDigest(const byte *digest, const byte *input, size_t length) 591 {Update(input, length); return Verify(digest);} 592 593 //! truncated version of Final() 594 virtual void TruncatedFinal(byte *digest, size_t digestSize) =0; 595 596 //! truncated version of CalculateDigest() 597 virtual void CalculateTruncatedDigest(byte *digest, size_t digestSize, const byte *input, size_t length) 598 {Update(input, length); TruncatedFinal(digest, digestSize);} 599 600 //! truncated version of Verify() 601 virtual bool TruncatedVerify(const byte *digest, size_t digestLength); 602 603 //! truncated version of VerifyDigest() 604 virtual bool VerifyTruncatedDigest(const byte *digest, size_t digestLength, const byte *input, size_t length) 605 {Update(input, length); return TruncatedVerify(digest, digestLength);} 606 607protected: 608 void ThrowIfInvalidTruncatedSize(size_t size) const; 609}; 610 611typedef HashTransformation HashFunction; 612 613//! interface for one direction (encryption or decryption) of a block cipher 614/*! \note These objects usually should not be used directly. See BlockTransformation for more details. */ 615class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockCipher : public SimpleKeyingInterface, public BlockTransformation 616{ 617protected: 618 const Algorithm & GetAlgorithm() const {return *this;} 619}; 620 621//! interface for one direction (encryption or decryption) of a stream cipher or cipher mode 622class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SymmetricCipher : public SimpleKeyingInterface, public StreamTransformation 623{ 624protected: 625 const Algorithm & GetAlgorithm() const {return *this;} 626}; 627 628//! interface for message authentication codes 629class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE MessageAuthenticationCode : public SimpleKeyingInterface, public HashTransformation 630{ 631protected: 632 const Algorithm & GetAlgorithm() const {return *this;} 633}; 634 635//! interface for for one direction (encryption or decryption) of a stream cipher or block cipher mode with authentication 636/*! The StreamTransformation part of this interface is used to encrypt/decrypt the data, and the MessageAuthenticationCode part of this 637 interface is used to input additional authenticated data (AAD, which is MAC'ed but not encrypted), and to generate/verify the MAC. */ 638class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AuthenticatedSymmetricCipher : public MessageAuthenticationCode, public StreamTransformation 639{ 640public: 641 //! 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 642 class BadState : public Exception 643 { 644 public: 645 explicit BadState(const std::string &name, const char *message) : Exception(OTHER_ERROR, name + ": " + message) {} 646 explicit BadState(const std::string &name, const char *function, const char *state) : Exception(OTHER_ERROR, name + ": " + function + " was called before " + state) {} 647 }; 648 649 //! the maximum length of AAD that can be input before the encrypted data 650 virtual lword MaxHeaderLength() const =0; 651 //! the maximum length of encrypted data 652 virtual lword MaxMessageLength() const =0; 653 //! the maximum length of AAD that can be input after the encrypted data 654 virtual lword MaxFooterLength() const {return 0;} 655 //! if this function returns true, SpecifyDataLengths() must be called before attempting to input data 656 /*! This is the case for some schemes, such as CCM. */ 657 virtual bool NeedsPrespecifiedDataLengths() const {return false;} 658 //! this function only needs to be called if NeedsPrespecifiedDataLengths() returns true 659 void SpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength=0); 660 //! encrypt and generate MAC in one call. will truncate MAC if macSize < TagSize() 661 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); 662 //! decrypt and verify MAC in one call, returning true iff MAC is valid. will assume MAC is truncated if macLength < TagSize() 663 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); 664 665 // redeclare this to avoid compiler ambiguity errors 666 virtual std::string AlgorithmName() const =0; 667 668protected: 669 const Algorithm & GetAlgorithm() const {return *static_cast<const MessageAuthenticationCode *>(this);} 670 virtual void UncheckedSpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength) {} 671}; 672 673#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY 674typedef SymmetricCipher StreamCipher; 675#endif 676 677//! interface for random number generators 678/*! All return values are uniformly distributed over the range specified. 679*/ 680class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomNumberGenerator : public Algorithm 681{ 682public: 683 //! update RNG state with additional unpredictable values 684 virtual void IncorporateEntropy(const byte *input, size_t length) {throw NotImplemented("RandomNumberGenerator: IncorporateEntropy not implemented");} 685 686 //! returns true if IncorporateEntropy is implemented 687 virtual bool CanIncorporateEntropy() const {return false;} 688 689 //! generate new random byte and return it 690 virtual byte GenerateByte(); 691 692 //! generate new random bit and return it 693 /*! Default implementation is to call GenerateByte() and return its lowest bit. */ 694 virtual unsigned int GenerateBit(); 695 696 //! generate a random 32 bit word in the range min to max, inclusive 697 virtual word32 GenerateWord32(word32 a=0, word32 b=0xffffffffL); 698 699 //! generate random array of bytes 700 virtual void GenerateBlock(byte *output, size_t size); 701 702 //! generate and discard n bytes 703 virtual void DiscardBytes(size_t n); 704 705 //! generate random bytes as input to a BufferedTransformation 706 virtual void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length); 707 708 //! randomly shuffle the specified array, resulting permutation is uniformly distributed 709 template <class IT> void Shuffle(IT begin, IT end) 710 { 711 for (; begin != end; ++begin) 712 std::iter_swap(begin, begin + GenerateWord32(0, end-begin-1)); 713 } 714 715#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY 716 byte GetByte() {return GenerateByte();} 717 unsigned int GetBit() {return GenerateBit();} 718 word32 GetLong(word32 a=0, word32 b=0xffffffffL) {return GenerateWord32(a, b);} 719 word16 GetShort(word16 a=0, word16 b=0xffff) {return (word16)GenerateWord32(a, b);} 720 void GetBlock(byte *output, size_t size) {GenerateBlock(output, size);} 721#endif 722}; 723 724//! returns a reference that can be passed to functions that ask for a RNG but doesn't actually use it 725CRYPTOPP_DLL RandomNumberGenerator & CRYPTOPP_API NullRNG(); 726 727class WaitObjectContainer; 728class CallStack; 729 730//! interface for objects that you can wait for 731 732class CRYPTOPP_NO_VTABLE Waitable 733{ 734public: 735 virtual ~Waitable() {} 736 737 //! maximum number of wait objects that this object can return 738 virtual unsigned int GetMaxWaitObjectCount() const =0; 739 //! put wait objects into container 740 /*! \param callStack is used for tracing no wait loops, example: 741 something.GetWaitObjects(c, CallStack("my func after X", 0)); 742 - or in an outer GetWaitObjects() method that itself takes a callStack parameter: 743 innerThing.GetWaitObjects(c, CallStack("MyClass::GetWaitObjects at X", &callStack)); */ 744 virtual void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) =0; 745 //! wait on this object 746 /*! same as creating an empty container, calling GetWaitObjects(), and calling Wait() on the container */ 747 bool Wait(unsigned long milliseconds, CallStack const& callStack); 748}; 749 750//! the default channel for BufferedTransformation, equal to the empty string 751extern CRYPTOPP_DLL const std::string DEFAULT_CHANNEL; 752 753//! channel for additional authenticated data, equal to "AAD" 754extern CRYPTOPP_DLL const std::string AAD_CHANNEL; 755 756//! interface for buffered transformations 757 758/*! BufferedTransformation is a generalization of BlockTransformation, 759 StreamTransformation, and HashTransformation. 760 761 A buffered transformation is an object that takes a stream of bytes 762 as input (this may be done in stages), does some computation on them, and 763 then places the result into an internal buffer for later retrieval. Any 764 partial result already in the output buffer is not modified by further 765 input. 766 767 If a method takes a "blocking" parameter, and you 768 pass "false" for it, the method will return before all input has been processed if 769 the input cannot be processed without waiting (for network buffers to become available, for example). 770 In this case the method will return true 771 or a non-zero integer value. When this happens you must continue to call the method with the same 772 parameters until it returns false or zero, before calling any other method on it or 773 attached BufferedTransformation. The integer return value in this case is approximately 774 the number of bytes left to be processed, and can be used to implement a progress bar. 775 776 For functions that take a "propagation" parameter, propagation != 0 means pass on the signal to attached 777 BufferedTransformation objects, with propagation decremented at each step until it reaches 0. 778 -1 means unlimited propagation. 779 780 \nosubgrouping 781*/ 782class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BufferedTransformation : public Algorithm, public Waitable 783{ 784public: 785 // placed up here for CW8 786 static const std::string &NULL_CHANNEL; // same as DEFAULT_CHANNEL, for backwards compatibility 787 788 BufferedTransformation() : Algorithm(false) {} 789 790 //! return a reference to this object 791 /*! This function is useful for passing a temporary BufferedTransformation object to a 792 function that takes a non-const reference. */ 793 BufferedTransformation& Ref() {return *this;} 794 795 //! \name INPUT 796 //@{ 797 //! input a byte for processing 798 size_t Put(byte inByte, bool blocking=true) 799 {return Put(&inByte, 1, blocking);} 800 //! input multiple bytes 801 size_t Put(const byte *inString, size_t length, bool blocking=true) 802 {return Put2(inString, length, 0, blocking);} 803 804 //! input a 16-bit word 805 size_t PutWord16(word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); 806 //! input a 32-bit word 807 size_t PutWord32(word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); 808 809 //! request space which can be written into by the caller, and then used as input to Put() 810 /*! \param size is requested size (as a hint) for input, and size of the returned space for output */ 811 /*! \note The purpose of this method is to help avoid doing extra memory allocations. */ 812 virtual byte * CreatePutSpace(size_t &size) {size=0; return NULL;} 813 814 virtual bool CanModifyInput() const {return false;} 815 816 //! input multiple bytes that may be modified by callee 817 size_t PutModifiable(byte *inString, size_t length, bool blocking=true) 818 {return PutModifiable2(inString, length, 0, blocking);} 819 820 bool MessageEnd(int propagation=-1, bool blocking=true) 821 {return !!Put2(NULL, 0, propagation < 0 ? -1 : propagation+1, blocking);} 822 size_t PutMessageEnd(const byte *inString, size_t length, int propagation=-1, bool blocking=true) 823 {return Put2(inString, length, propagation < 0 ? -1 : propagation+1, blocking);} 824 825 //! input multiple bytes for blocking or non-blocking processing 826 /*! \param messageEnd means how many filters to signal MessageEnd to, including this one */ 827 virtual size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) =0; 828 //! input multiple bytes that may be modified by callee for blocking or non-blocking processing 829 /*! \param messageEnd means how many filters to signal MessageEnd to, including this one */ 830 virtual size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking) 831 {return Put2(inString, length, messageEnd, blocking);} 832 833 //! thrown by objects that have not implemented nonblocking input processing 834 struct BlockingInputOnly : public NotImplemented 835 {BlockingInputOnly(const std::string &s) : NotImplemented(s + ": Nonblocking input is not implemented by this object.") {}}; 836 //@} 837 838 //! \name WAITING 839 //@{ 840 unsigned int GetMaxWaitObjectCount() const; 841 void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); 842 //@} 843 844 //! \name SIGNALS 845 //@{ 846 virtual void IsolatedInitialize(const NameValuePairs ¶meters) {throw NotImplemented("BufferedTransformation: this object can't be reinitialized");} 847 virtual bool IsolatedFlush(bool hardFlush, bool blocking) =0; 848 virtual bool IsolatedMessageSeriesEnd(bool blocking) {return false;} 849 850 //! initialize or reinitialize this object 851 virtual void Initialize(const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1); 852 //! flush buffered input and/or output 853 /*! \param hardFlush is used to indicate whether all data should be flushed 854 \note Hard flushes must be used with care. It means try to process and output everything, even if 855 there may not be enough data to complete the action. For example, hard flushing a HexDecoder would 856 cause an error if you do it after inputing an odd number of hex encoded characters. 857 For some types of filters, for example ZlibDecompressor, hard flushes can only 858 be done at "synchronization points". These synchronization points are positions in the data 859 stream that are created by hard flushes on the corresponding reverse filters, in this 860 example ZlibCompressor. This is useful when zlib compressed data is moved across a 861 network in packets and compression state is preserved across packets, as in the ssh2 protocol. 862 */ 863 virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true); 864 //! mark end of a series of messages 865 /*! There should be a MessageEnd immediately before MessageSeriesEnd. */ 866 virtual bool MessageSeriesEnd(int propagation=-1, bool blocking=true); 867 868 //! set propagation of automatically generated and transferred signals 869 /*! propagation == 0 means do not automaticly generate signals */ 870 virtual void SetAutoSignalPropagation(int propagation) {} 871 872 //! 873 virtual int GetAutoSignalPropagation() const {return 0;} 874public: 875 876#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY 877 void Close() {MessageEnd();} 878#endif 879 //@} 880 881 //! \name RETRIEVAL OF ONE MESSAGE 882 //@{ 883 //! returns number of bytes that is currently ready for retrieval 884 /*! All retrieval functions return the actual number of bytes 885 retrieved, which is the lesser of the request number and 886 MaxRetrievable(). */ 887 virtual lword MaxRetrievable() const; 888 889 //! returns whether any bytes are currently ready for retrieval 890 virtual bool AnyRetrievable() const; 891 892 //! try to retrieve a single byte 893 virtual size_t Get(byte &outByte); 894 //! try to retrieve multiple bytes 895 virtual size_t Get(byte *outString, size_t getMax); 896 897 //! peek at the next byte without removing it from the output buffer 898 virtual size_t Peek(byte &outByte) const; 899 //! peek at multiple bytes without removing them from the output buffer 900 virtual size_t Peek(byte *outString, size_t peekMax) const; 901 902 //! try to retrieve a 16-bit word 903 size_t GetWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER); 904 //! try to retrieve a 32-bit word 905 size_t GetWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER); 906 907 //! try to peek at a 16-bit word 908 size_t PeekWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER) const; 909 //! try to peek at a 32-bit word 910 size_t PeekWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER) const; 911 912 //! move transferMax bytes of the buffered output to target as input 913 lword TransferTo(BufferedTransformation &target, lword transferMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) 914 {TransferTo2(target, transferMax, channel); return transferMax;} 915 916 //! discard skipMax bytes from the output buffer 917 virtual lword Skip(lword skipMax=LWORD_MAX); 918 919 //! copy copyMax bytes of the buffered output to target as input 920 lword CopyTo(BufferedTransformation &target, lword copyMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) const 921 {return CopyRangeTo(target, 0, copyMax, channel);} 922 923 //! copy copyMax bytes of the buffered output, starting at position (relative to current position), to target as input 924 lword CopyRangeTo(BufferedTransformation &target, lword position, lword copyMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) const 925 {lword i = position; CopyRangeTo2(target, i, i+copyMax, channel); return i-position;} 926 927#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY 928 unsigned long MaxRetrieveable() const {return MaxRetrievable();} 929#endif 930 //@} 931 932 //! \name RETRIEVAL OF MULTIPLE MESSAGES 933 //@{ 934 //! 935 virtual lword TotalBytesRetrievable() const; 936 //! number of times MessageEnd() has been received minus messages retrieved or skipped 937 virtual unsigned int NumberOfMessages() const; 938 //! returns true if NumberOfMessages() > 0 939 virtual bool AnyMessages() const; 940 //! start retrieving the next message 941 /*! 942 Returns false if no more messages exist or this message 943 is not completely retrieved. 944 */ 945 virtual bool GetNextMessage(); 946 //! skip count number of messages 947 virtual unsigned int SkipMessages(unsigned int count=UINT_MAX); 948 //! 949 unsigned int TransferMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL) 950 {TransferMessagesTo2(target, count, channel); return count;} 951 //! 952 unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL) const; 953 954 //! 955 virtual void SkipAll(); 956 //! 957 void TransferAllTo(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL) 958 {TransferAllTo2(target, channel);} 959 //! 960 void CopyAllTo(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL) const; 961 962 virtual bool GetNextMessageSeries() {return false;} 963 virtual unsigned int NumberOfMessagesInThisSeries() const {return NumberOfMessages();} 964 virtual unsigned int NumberOfMessageSeries() const {return 0;} 965 //@} 966 967 //! \name NON-BLOCKING TRANSFER OF OUTPUT 968 //@{ 969 //! upon return, byteCount contains number of bytes that have finished being transfered, and returns the number of bytes left in the current transfer block 970 virtual size_t TransferTo2(BufferedTransformation &target, lword &byteCount, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) =0; 971 //! 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 972 virtual size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const =0; 973 //! upon return, messageCount contains number of messages that have finished being transfered, and returns the number of bytes left in the current transfer block 974 size_t TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); 975 //! returns the number of bytes left in the current transfer block 976 size_t TransferAllTo2(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); 977 //@} 978 979 //! \name CHANNELS 980 //@{ 981 struct NoChannelSupport : public NotImplemented 982 {NoChannelSupport(const std::string &name) : NotImplemented(name + ": this object doesn't support multiple channels") {}}; 983 struct InvalidChannelName : public InvalidArgument 984 {InvalidChannelName(const std::string &name, const std::string &channel) : InvalidArgument(name + ": unexpected channel name \"" + channel + "\"") {}}; 985 986 size_t ChannelPut(const std::string &channel, byte inByte, bool blocking=true) 987 {return ChannelPut(channel, &inByte, 1, blocking);} 988 size_t ChannelPut(const std::string &channel, const byte *inString, size_t length, bool blocking=true) 989 {return ChannelPut2(channel, inString, length, 0, blocking);} 990 991 size_t ChannelPutModifiable(const std::string &channel, byte *inString, size_t length, bool blocking=true) 992 {return ChannelPutModifiable2(channel, inString, length, 0, blocking);} 993 994 size_t ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); 995 size_t ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); 996 997 bool ChannelMessageEnd(const std::string &channel, int propagation=-1, bool blocking=true) 998 {return !!ChannelPut2(channel, NULL, 0, propagation < 0 ? -1 : propagation+1, blocking);} 999 size_t ChannelPutMessageEnd(const std::string &channel, const byte *inString, size_t length, int propagation=-1, bool blocking=true) 1000 {return ChannelPut2(channel, inString, length, propagation < 0 ? -1 : propagation+1, blocking);} 1001 1002 virtual byte * ChannelCreatePutSpace(const std::string &channel, size_t &size); 1003 1004 virtual size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking); 1005 virtual size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking); 1006 1007 virtual bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true); 1008 virtual bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true); 1009 1010 virtual void SetRetrievalChannel(const std::string &channel); 1011 //@} 1012 1013 //! \name ATTACHMENT 1014 /*! Some BufferedTransformation objects (e.g. Filter objects) 1015 allow other BufferedTransformation objects to be attached. When 1016 this is done, the first object instead of buffering its output, 1017 sents that output to the attached object as input. The entire 1018 attachment chain is deleted when the anchor object is destructed. 1019 */ 1020 //@{ 1021 //! returns whether this object allows attachment 1022 virtual bool Attachable() {return false;} 1023 //! returns the object immediately attached to this object or NULL for no attachment 1024 virtual BufferedTransformation *AttachedTransformation() {assert(!Attachable()); return 0;} 1025 //! 1026 virtual const BufferedTransformation *AttachedTransformation() const 1027 {return const_cast<BufferedTransformation *>(this)->AttachedTransformation();} 1028 //! delete the current attachment chain and replace it with newAttachment 1029 virtual void Detach(BufferedTransformation *newAttachment = 0) 1030 {assert(!Attachable()); throw NotImplemented("BufferedTransformation: this object is not attachable");} 1031 //! add newAttachment to the end of attachment chain 1032 virtual void Attach(BufferedTransformation *newAttachment); 1033 //@} 1034 1035protected: 1036 static int DecrementPropagation(int propagation) 1037 {return propagation != 0 ? propagation - 1 : 0;} 1038 1039private: 1040 byte m_buf[4]; // for ChannelPutWord16 and ChannelPutWord32, to ensure buffer isn't deallocated before non-blocking operation completes 1041}; 1042 1043//! returns a reference to a BufferedTransformation object that discards all input 1044BufferedTransformation & TheBitBucket(); 1045 1046//! interface for crypto material, such as public and private keys, and crypto parameters 1047 1048class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CryptoMaterial : public NameValuePairs 1049{ 1050public: 1051 //! exception thrown when invalid crypto material is detected 1052 class CRYPTOPP_DLL InvalidMaterial : public InvalidDataFormat 1053 { 1054 public: 1055 explicit InvalidMaterial(const std::string &s) : InvalidDataFormat(s) {} 1056 }; 1057 1058 //! assign values from source to this object 1059 /*! \note This function can be used to create a public key from a private key. */ 1060 virtual void AssignFrom(const NameValuePairs &source) =0; 1061 1062 //! check this object for errors 1063 /*! \param level denotes the level of thoroughness: 1064 0 - using this object won't cause a crash or exception (rng is ignored) 1065 1 - this object will probably function (encrypt, sign, etc.) correctly (but may not check for weak keys and such) 1066 2 - make sure this object will function correctly, and do reasonable security checks 1067 3 - do checks that may take a long time 1068 \return true if the tests pass */ 1069 virtual bool Validate(RandomNumberGenerator &rng, unsigned int level) const =0; 1070 1071 //! throws InvalidMaterial if this object fails Validate() test 1072 virtual void ThrowIfInvalid(RandomNumberGenerator &rng, unsigned int level) const 1073 {if (!Validate(rng, level)) throw InvalidMaterial("CryptoMaterial: this object contains invalid values");} 1074 1075// virtual std::vector<std::string> GetSupportedFormats(bool includeSaveOnly=false, bool includeLoadOnly=false); 1076 1077 //! save key into a BufferedTransformation 1078 virtual void Save(BufferedTransformation &bt) const 1079 {throw NotImplemented("CryptoMaterial: this object does not support saving");} 1080 1081 //! load key from a BufferedTransformation 1082 /*! \throws KeyingErr if decode fails 1083 \note Generally does not check that the key is valid. 1084 Call ValidateKey() or ThrowIfInvalidKey() to check that. */ 1085 virtual void Load(BufferedTransformation &bt) 1086 {throw NotImplemented("CryptoMaterial: this object does not support loading");} 1087 1088 //! \return whether this object supports precomputation 1089 virtual bool SupportsPrecomputation() const {return false;} 1090 //! do precomputation 1091 /*! The exact semantics of Precompute() is varies, but 1092 typically it means calculate a table of n objects 1093 that can be used later to speed up computation. */ 1094 virtual void Precompute(unsigned int n) 1095 {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");} 1096 //! retrieve previously saved precomputation 1097 virtual void LoadPrecomputation(BufferedTransformation &storedPrecomputation) 1098 {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");} 1099 //! save precomputation for later use 1100 virtual void SavePrecomputation(BufferedTransformation &storedPrecomputation) const 1101 {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");} 1102 1103 // for internal library use 1104 void DoQuickSanityCheck() const {ThrowIfInvalid(NullRNG(), 0);} 1105 1106#if (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) 1107 // Sun Studio 11/CC 5.8 workaround: it generates incorrect code when casting to an empty virtual base class 1108 char m_sunCCworkaround; 1109#endif 1110}; 1111 1112//! interface for generatable crypto material, such as private keys and crypto parameters 1113 1114class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GeneratableCryptoMaterial : virtual public CryptoMaterial 1115{ 1116public: 1117 //! generate a random key or crypto parameters 1118 /*! \throws KeyingErr if algorithm parameters are invalid, or if a key can't be generated 1119 (e.g., if this is a public key object) */ 1120 virtual void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms = g_nullNameValuePairs) 1121 {throw NotImplemented("GeneratableCryptoMaterial: this object does not support key/parameter generation");} 1122 1123 //! calls the above function with a NameValuePairs object that just specifies "KeySize" 1124 void GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize); 1125}; 1126 1127//! interface for public keys 1128 1129class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PublicKey : virtual public CryptoMaterial 1130{ 1131}; 1132 1133//! interface for private keys 1134 1135class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PrivateKey : public GeneratableCryptoMaterial 1136{ 1137}; 1138 1139//! interface for crypto prameters 1140 1141class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CryptoParameters : public GeneratableCryptoMaterial 1142{ 1143}; 1144 1145//! interface for asymmetric algorithms 1146 1147class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AsymmetricAlgorithm : public Algorithm 1148{ 1149public: 1150 //! returns a reference to the crypto material used by this object 1151 virtual CryptoMaterial & AccessMaterial() =0; 1152 //! returns a const reference to the crypto material used by this object 1153 virtual const CryptoMaterial & GetMaterial() const =0; 1154 1155 //! for backwards compatibility, calls AccessMaterial().Load(bt) 1156 void BERDecode(BufferedTransformation &bt) 1157 {AccessMaterial().Load(bt);} 1158 //! for backwards compatibility, calls GetMaterial().Save(bt) 1159 void DEREncode(BufferedTransformation &bt) const 1160 {GetMaterial().Save(bt);} 1161}; 1162 1163//! interface for asymmetric algorithms using public keys 1164 1165class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PublicKeyAlgorithm : public AsymmetricAlgorithm 1166{ 1167public: 1168 // VC60 workaround: no co-variant return type 1169 CryptoMaterial & AccessMaterial() {return AccessPublicKey();} 1170 const CryptoMaterial & GetMaterial() const {return GetPublicKey();} 1171 1172 virtual PublicKey & AccessPublicKey() =0; 1173 virtual const PublicKey & GetPublicKey() const {return const_cast<PublicKeyAlgorithm *>(this)->AccessPublicKey();} 1174}; 1175 1176//! interface for asymmetric algorithms using private keys 1177 1178class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PrivateKeyAlgorithm : public AsymmetricAlgorithm 1179{ 1180public: 1181 CryptoMaterial & AccessMaterial() {return AccessPrivateKey();} 1182 const CryptoMaterial & GetMaterial() const {return GetPrivateKey();} 1183 1184 virtual PrivateKey & AccessPrivateKey() =0; 1185 virtual const PrivateKey & GetPrivateKey() const {return const_cast<PrivateKeyAlgorithm *>(this)->AccessPrivateKey();} 1186}; 1187 1188//! interface for key agreement algorithms 1189 1190class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE KeyAgreementAlgorithm : public AsymmetricAlgorithm 1191{ 1192public: 1193 CryptoMaterial & AccessMaterial() {return AccessCryptoParameters();} 1194 const CryptoMaterial & GetMaterial() const {return GetCryptoParameters();} 1195 1196 virtual CryptoParameters & AccessCryptoParameters() =0; 1197 virtual const CryptoParameters & GetCryptoParameters() const {return const_cast<KeyAgreementAlgorithm *>(this)->AccessCryptoParameters();} 1198}; 1199 1200//! interface for public-key encryptors and decryptors 1201 1202/*! This class provides an interface common to encryptors and decryptors 1203 for querying their plaintext and ciphertext lengths. 1204*/ 1205class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_CryptoSystem 1206{ 1207public: 1208 virtual ~PK_CryptoSystem() {} 1209 1210 //! maximum length of plaintext for a given ciphertext length 1211 /*! \note This function returns 0 if ciphertextLength is not valid (too long or too short). */ 1212 virtual size_t MaxPlaintextLength(size_t ciphertextLength) const =0; 1213 1214 //! calculate length of ciphertext given length of plaintext 1215 /*! \note This function returns 0 if plaintextLength is not valid (too long). */ 1216 virtual size_t CiphertextLength(size_t plaintextLength) const =0; 1217 1218 //! this object supports the use of the parameter with the given name 1219 /*! some possible parameter names: EncodingParameters, KeyDerivationParameters */ 1220 virtual bool ParameterSupported(const char *name) const =0; 1221 1222 //! return fixed ciphertext length, if one exists, otherwise return 0 1223 /*! \note "Fixed" here means length of ciphertext does not depend on length of plaintext. 1224 It usually does depend on the key length. */ 1225 virtual size_t FixedCiphertextLength() const {return 0;} 1226 1227 //! return maximum plaintext length given the fixed ciphertext length, if one exists, otherwise return 0 1228 virtual size_t FixedMaxPlaintextLength() const {return 0;} 1229 1230#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY 1231 size_t MaxPlainTextLength(size_t cipherTextLength) const {return MaxPlaintextLength(cipherTextLength);} 1232 size_t CipherTextLength(size_t plainTextLength) const {return CiphertextLength(plainTextLength);} 1233#endif 1234}; 1235 1236//! interface for public-key encryptors 1237class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Encryptor : public PK_CryptoSystem, public PublicKeyAlgorithm 1238{ 1239public: 1240 //! exception thrown when trying to encrypt plaintext of invalid length 1241 class CRYPTOPP_DLL InvalidPlaintextLength : public Exception 1242 { 1243 public: 1244 InvalidPlaintextLength() : Exception(OTHER_ERROR, "PK_Encryptor: invalid plaintext length") {} 1245 }; 1246 1247 //! encrypt a byte string 1248 /*! \pre CiphertextLength(plaintextLength) != 0 (i.e., plaintext isn't too long) 1249 \pre size of ciphertext == CiphertextLength(plaintextLength) 1250 */ 1251 virtual void Encrypt(RandomNumberGenerator &rng, 1252 const byte *plaintext, size_t plaintextLength, 1253 byte *ciphertext, const NameValuePairs ¶meters = g_nullNameValuePairs) const =0; 1254 1255 //! create a new encryption filter 1256 /*! \note The caller is responsible for deleting the returned pointer. 1257 \note Encoding parameters should be passed in the "EP" channel. 1258 */ 1259 virtual BufferedTransformation * CreateEncryptionFilter(RandomNumberGenerator &rng, 1260 BufferedTransformation *attachment=NULL, const NameValuePairs ¶meters = g_nullNameValuePairs) const; 1261}; 1262 1263//! interface for public-key decryptors 1264 1265class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Decryptor : public PK_CryptoSystem, public PrivateKeyAlgorithm 1266{ 1267public: 1268 //! decrypt a byte string, and return the length of plaintext 1269 /*! \pre size of plaintext == MaxPlaintextLength(ciphertextLength) bytes. 1270 \return the actual length of the plaintext, indication that decryption failed. 1271 */ 1272 virtual DecodingResult Decrypt(RandomNumberGenerator &rng, 1273 const byte *ciphertext, size_t ciphertextLength, 1274 byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const =0; 1275 1276 //! create a new decryption filter 1277 /*! \note caller is responsible for deleting the returned pointer 1278 */ 1279 virtual BufferedTransformation * CreateDecryptionFilter(RandomNumberGenerator &rng, 1280 BufferedTransformation *attachment=NULL, const NameValuePairs ¶meters = g_nullNameValuePairs) const; 1281 1282 //! decrypt a fixed size ciphertext 1283 DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *ciphertext, byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const 1284 {return Decrypt(rng, ciphertext, FixedCiphertextLength(), plaintext, parameters);} 1285}; 1286 1287#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY 1288typedef PK_CryptoSystem PK_FixedLengthCryptoSystem; 1289typedef PK_Encryptor PK_FixedLengthEncryptor; 1290typedef PK_Decryptor PK_FixedLengthDecryptor; 1291#endif 1292 1293//! interface for public-key signers and verifiers 1294 1295/*! This class provides an interface common to signers and verifiers 1296 for querying scheme properties. 1297*/ 1298class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_SignatureScheme 1299{ 1300public: 1301 //! 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 1302 class CRYPTOPP_DLL InvalidKeyLength : public Exception 1303 { 1304 public: 1305 InvalidKeyLength(const std::string &message) : Exception(OTHER_ERROR, message) {} 1306 }; 1307 1308 //! 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 1309 class CRYPTOPP_DLL KeyTooShort : public InvalidKeyLength 1310 { 1311 public: 1312 KeyTooShort() : InvalidKeyLength("PK_Signer: key too short for this signature scheme") {} 1313 }; 1314 1315 virtual ~PK_SignatureScheme() {} 1316 1317 //! signature length if it only depends on the key, otherwise 0 1318 virtual size_t SignatureLength() const =0; 1319 1320 //! maximum signature length produced for a given length of recoverable message part 1321 virtual size_t MaxSignatureLength(size_t recoverablePartLength = 0) const {return SignatureLength();} 1322 1323 //! length of longest message that can be recovered, or 0 if this signature scheme does not support message recovery 1324 virtual size_t MaxRecoverableLength() const =0; 1325 1326 //! 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 1327 virtual size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const =0; 1328 1329 //! requires a random number generator to sign 1330 /*! if this returns false, NullRNG() can be passed to functions that take RandomNumberGenerator & */ 1331 virtual bool IsProbabilistic() const =0; 1332 1333 //! whether or not a non-recoverable message part can be signed 1334 virtual bool AllowNonrecoverablePart() const =0; 1335 1336 //! if this function returns true, during verification you must input the signature before the message, otherwise you can input it at anytime */ 1337 virtual bool SignatureUpfront() const {return false;} 1338 1339 //! whether you must input the recoverable part before the non-recoverable part during signing 1340 virtual bool RecoverablePartFirst() const =0; 1341}; 1342 1343//! interface for accumulating messages to be signed or verified 1344/*! Only Update() should be called 1345 on this class. No other functions inherited from HashTransformation should be called. 1346*/ 1347class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulator : public HashTransformation 1348{ 1349public: 1350 //! should not be called on PK_MessageAccumulator 1351 unsigned int DigestSize() const 1352 {throw NotImplemented("PK_MessageAccumulator: DigestSize() should not be called");} 1353 //! should not be called on PK_MessageAccumulator 1354 void TruncatedFinal(byte *digest, size_t digestSize) 1355 {throw NotImplemented("PK_MessageAccumulator: TruncatedFinal() should not be called");} 1356}; 1357 1358//! interface for public-key signers 1359 1360class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Signer : public PK_SignatureScheme, public PrivateKeyAlgorithm 1361{ 1362public: 1363 //! create a new HashTransformation to accumulate the message to be signed 1364 virtual PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const =0; 1365 1366 virtual void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const =0; 1367 1368 //! sign and delete messageAccumulator (even in case of exception thrown) 1369 /*! \pre size of signature == MaxSignatureLength() 1370 \return actual signature length 1371 */ 1372 virtual size_t Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const; 1373 1374 //! sign and restart messageAccumulator 1375 /*! \pre size of signature == MaxSignatureLength() 1376 \return actual signature length 1377 */ 1378 virtual size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const =0; 1379 1380 //! sign a message 1381 /*! \pre size of signature == MaxSignatureLength() 1382 \return actual signature length 1383 */ 1384 virtual size_t SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const; 1385 1386 //! sign a recoverable message 1387 /*! \pre size of signature == MaxSignatureLength(recoverableMessageLength) 1388 \return actual signature length 1389 */ 1390 virtual size_t SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, size_t recoverableMessageLength, 1391 const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, byte *signature) const; 1392}; 1393 1394//! interface for public-key signature verifiers 1395/*! The Recover* functions throw NotImplemented if the signature scheme does not support 1396 message recovery. 1397 The Verify* functions throw InvalidDataFormat if the scheme does support message 1398 recovery and the signature contains a non-empty recoverable message part. The 1399 Recovery* functions should be used in that case. 1400*/ 1401class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Verifier : public PK_SignatureScheme, public PublicKeyAlgorithm 1402{ 1403public: 1404 //! create a new HashTransformation to accumulate the message to be verified 1405 virtual PK_MessageAccumulator * NewVerificationAccumulator() const =0; 1406 1407 //! input signature into a message accumulator 1408 virtual void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const =0; 1409 1410 //! check whether messageAccumulator contains a valid signature and message, and delete messageAccumulator (even in case of exception thrown) 1411 virtual bool Verify(PK_MessageAccumulator *messageAccumulator) const; 1412 1413 //! check whether messageAccumulator contains a valid signature and message, and restart messageAccumulator 1414 virtual bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const =0; 1415 1416 //! check whether input signature is a valid signature for input message 1417 virtual bool VerifyMessage(const byte *message, size_t messageLen, 1418 const byte *signature, size_t signatureLength) const; 1419 1420 //! recover a message from its signature 1421 /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength) 1422 */ 1423 virtual DecodingResult Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const; 1424 1425 //! recover a message from its signature 1426 /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength) 1427 */ 1428 virtual DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const =0; 1429 1430 //! recover a message from its signature 1431 /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength) 1432 */ 1433 virtual DecodingResult RecoverMessage(byte *recoveredMessage, 1434 const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, 1435 const byte *signature, size_t signatureLength) const; 1436}; 1437 1438//! interface for domains of simple key agreement protocols 1439 1440/*! A key agreement domain is a set of parameters that must be shared 1441 by two parties in a key agreement protocol, along with the algorithms 1442 for generating key pairs and deriving agreed values. 1443*/ 1444class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyAgreementDomain : public KeyAgreementAlgorithm 1445{ 1446public: 1447 //! return length of agreed value produced 1448 virtual unsigned int AgreedValueLength() const =0; 1449 //! return length of private keys in this domain 1450 virtual unsigned int PrivateKeyLength() const =0; 1451 //! return length of public keys in this domain 1452 virtual unsigned int PublicKeyLength() const =0; 1453 //! generate private key 1454 /*! \pre size of privateKey == PrivateKeyLength() */ 1455 virtual void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0; 1456 //! generate public key 1457 /*! \pre size of publicKey == PublicKeyLength() */ 1458 virtual void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0; 1459 //! generate private/public key pair 1460 /*! \note equivalent to calling GeneratePrivateKey() and then GeneratePublicKey() */ 1461 virtual void GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const; 1462 //! derive agreed value from your private key and couterparty's public key, return false in case of failure 1463 /*! \note If you have previously validated the public key, use validateOtherPublicKey=false to save time. 1464 \pre size of agreedValue == AgreedValueLength() 1465 \pre length of privateKey == PrivateKeyLength() 1466 \pre length of otherPublicKey == PublicKeyLength() 1467 */ 1468 virtual bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const =0; 1469 1470#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY 1471 bool ValidateDomainParameters(RandomNumberGenerator &rng) const 1472 {return GetCryptoParameters().Validate(rng, 2);} 1473#endif 1474}; 1475 1476//! interface for domains of authenticated key agreement protocols 1477 1478/*! In an authenticated key agreement protocol, each party has two 1479 key pairs. The long-lived key pair is called the static key pair, 1480 and the short-lived key pair is called the ephemeral key pair. 1481*/ 1482class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AuthenticatedKeyAgreementDomain : public KeyAgreementAlgorithm 1483{ 1484public: 1485 //! return length of agreed value produced 1486 virtual unsigned int AgreedValueLength() const =0; 1487 1488 //! return length of static private keys in this domain 1489 virtual unsigned int StaticPrivateKeyLength() const =0; 1490 //! return length of static public keys in this domain 1491 virtual unsigned int StaticPublicKeyLength() const =0; 1492 //! generate static private key 1493 /*! \pre size of privateKey == PrivateStaticKeyLength() */ 1494 virtual void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0; 1495 //! generate static public key 1496 /*! \pre size of publicKey == PublicStaticKeyLength() */ 1497 virtual void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0; 1498 //! generate private/public key pair 1499 /*! \note equivalent to calling GenerateStaticPrivateKey() and then GenerateStaticPublicKey() */ 1500 virtual void GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const; 1501 1502 //! return length of ephemeral private keys in this domain 1503 virtual unsigned int EphemeralPrivateKeyLength() const =0; 1504 //! return length of ephemeral public keys in this domain 1505 virtual unsigned int EphemeralPublicKeyLength() const =0; 1506 //! generate ephemeral private key 1507 /*! \pre size of privateKey == PrivateEphemeralKeyLength() */ 1508 virtual void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0; 1509 //! generate ephemeral public key 1510 /*! \pre size of publicKey == PublicEphemeralKeyLength() */ 1511 virtual void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0; 1512 //! generate private/public key pair 1513 /*! \note equivalent to calling GenerateEphemeralPrivateKey() and then GenerateEphemeralPublicKey() */ 1514 virtual void GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const; 1515 1516 //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure 1517 /*! \note The ephemeral public key will always be validated. 1518 If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time. 1519 \pre size of agreedValue == AgreedValueLength() 1520 \pre length of staticPrivateKey == StaticPrivateKeyLength() 1521 \pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength() 1522 \pre length of staticOtherPublicKey == StaticPublicKeyLength() 1523 \pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength() 1524 */ 1525 virtual bool Agree(byte *agreedValue, 1526 const byte *staticPrivateKey, const byte *ephemeralPrivateKey, 1527 const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, 1528 bool validateStaticOtherPublicKey=true) const =0; 1529 1530#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY 1531 bool ValidateDomainParameters(RandomNumberGenerator &rng) const 1532 {return GetCryptoParameters().Validate(rng, 2);} 1533#endif 1534}; 1535 1536// interface for password authenticated key agreement protocols, not implemented yet 1537#if 0 1538//! interface for protocol sessions 1539/*! The methods should be called in the following order: 1540 1541 InitializeSession(rng, parameters); // or call initialize method in derived class 1542 while (true) 1543 { 1544 if (OutgoingMessageAvailable()) 1545 { 1546 length = GetOutgoingMessageLength(); 1547 GetOutgoingMessage(message); 1548 ; // send outgoing message 1549 } 1550 1551 if (LastMessageProcessed()) 1552 break; 1553 1554 ; // receive incoming message 1555 ProcessIncomingMessage(message); 1556 } 1557 ; // call methods in derived class to obtain result of protocol session 1558*/ 1559class ProtocolSession 1560{ 1561public: 1562 //! exception thrown when an invalid protocol message is processed 1563 class ProtocolError : public Exception 1564 { 1565 public: 1566 ProtocolError(ErrorType errorType, const std::string &s) : Exception(errorType, s) {} 1567 }; 1568 1569 //! exception thrown when a function is called unexpectedly 1570 /*! for example calling ProcessIncomingMessage() when ProcessedLastMessage() == true */ 1571 class UnexpectedMethodCall : public Exception 1572 { 1573 public: 1574 UnexpectedMethodCall(const std::string &s) : Exception(OTHER_ERROR, s) {} 1575 }; 1576 1577 ProtocolSession() : m_rng(NULL), m_throwOnProtocolError(true), m_validState(false) {} 1578 virtual ~ProtocolSession() {} 1579 1580 virtual void InitializeSession(RandomNumberGenerator &rng, const NameValuePairs ¶meters) =0; 1581 1582 bool GetThrowOnProtocolError() const {return m_throwOnProtocolError;} 1583 void SetThrowOnProtocolError(bool throwOnProtocolError) {m_throwOnProtocolError = throwOnProtocolError;} 1584 1585 bool HasValidState() const {return m_validState;} 1586 1587 virtual bool OutgoingMessageAvailable() const =0; 1588 virtual unsigned int GetOutgoingMessageLength() const =0; 1589 virtual void GetOutgoingMessage(byte *message) =0; 1590 1591 virtual bool LastMessageProcessed() const =0; 1592 virtual void ProcessIncomingMessage(const byte *message, unsigned int messageLength) =0; 1593 1594protected: 1595 void HandleProtocolError(Exception::ErrorType errorType, const std::string &s) const; 1596 void CheckAndHandleInvalidState() const; 1597 void SetValidState(bool valid) {m_validState = valid;} 1598 1599 RandomNumberGenerator *m_rng; 1600 1601private: 1602 bool m_throwOnProtocolError, m_validState; 1603}; 1604 1605class KeyAgreementSession : public ProtocolSession 1606{ 1607public: 1608 virtual unsigned int GetAgreedValueLength() const =0; 1609 virtual void GetAgreedValue(byte *agreedValue) const =0; 1610}; 1611 1612class PasswordAuthenticatedKeyAgreementSession : public KeyAgreementSession 1613{ 1614public: 1615 void InitializePasswordAuthenticatedKeyAgreementSession(RandomNumberGenerator &rng, 1616 const byte *myId, unsigned int myIdLength, 1617 const byte *counterPartyId, unsigned int counterPartyIdLength, 1618 const byte *passwordOrVerifier, unsigned int passwordOrVerifierLength); 1619}; 1620 1621class PasswordAuthenticatedKeyAgreementDomain : public KeyAgreementAlgorithm 1622{ 1623public: 1624 //! return whether the domain parameters stored in this object are valid 1625 virtual bool ValidateDomainParameters(RandomNumberGenerator &rng) const 1626 {return GetCryptoParameters().Validate(rng, 2);} 1627 1628 virtual unsigned int GetPasswordVerifierLength(const byte *password, unsigned int passwordLength) const =0; 1629 virtual void GeneratePasswordVerifier(RandomNumberGenerator &rng, const byte *userId, unsigned int userIdLength, const byte *password, unsigned int passwordLength, byte *verifier) const =0; 1630 1631 enum RoleFlags {CLIENT=1, SERVER=2, INITIATOR=4, RESPONDER=8}; 1632 1633 virtual bool IsValidRole(unsigned int role) =0; 1634 virtual PasswordAuthenticatedKeyAgreementSession * CreateProtocolSession(unsigned int role) const =0; 1635}; 1636#endif 1637 1638//! BER Decode Exception Class, may be thrown during an ASN1 BER decode operation 1639class CRYPTOPP_DLL BERDecodeErr : public InvalidArgument 1640{ 1641public: 1642 BERDecodeErr() : InvalidArgument("BER decode error") {} 1643 BERDecodeErr(const std::string &s) : InvalidArgument(s) {} 1644}; 1645 1646//! interface for encoding and decoding ASN1 objects 1647class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ASN1Object 1648{ 1649public: 1650 virtual ~ASN1Object() {} 1651 //! decode this object from a BufferedTransformation, using BER (Basic Encoding Rules) 1652 virtual void BERDecode(BufferedTransformation &bt) =0; 1653 //! encode this object into a BufferedTransformation, using DER (Distinguished Encoding Rules) 1654 virtual void DEREncode(BufferedTransformation &bt) const =0; 1655 //! encode this object into a BufferedTransformation, using BER 1656 /*! this may be useful if DEREncode() would be too inefficient */ 1657 virtual void BEREncode(BufferedTransformation &bt) const {DEREncode(bt);} 1658}; 1659 1660#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY 1661typedef PK_SignatureScheme PK_SignatureSystem; 1662typedef SimpleKeyAgreementDomain PK_SimpleKeyAgreementDomain; 1663typedef AuthenticatedKeyAgreementDomain PK_AuthenticatedKeyAgreementDomain; 1664#endif 1665 1666NAMESPACE_END 1667 1668#endif 1669