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