Crypto++
gcm.h
1 #ifndef CRYPTOPP_GCM_H
2 #define CRYPTOPP_GCM_H
3 
4 #include "authenc.h"
5 #include "modes.h"
6 
7 NAMESPACE_BEGIN(CryptoPP)
8 
9 //! .
10 enum GCM_TablesOption {GCM_2K_Tables, GCM_64K_Tables};
11 
12 //! .
13 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GCM_Base : public AuthenticatedSymmetricCipherBase
14 {
15 public:
16  // AuthenticatedSymmetricCipher
17  std::string AlgorithmName() const
18  {return GetBlockCipher().AlgorithmName() + std::string("/GCM");}
19  size_t MinKeyLength() const
20  {return GetBlockCipher().MinKeyLength();}
21  size_t MaxKeyLength() const
22  {return GetBlockCipher().MaxKeyLength();}
23  size_t DefaultKeyLength() const
24  {return GetBlockCipher().DefaultKeyLength();}
25  size_t GetValidKeyLength(size_t n) const
26  {return GetBlockCipher().GetValidKeyLength(n);}
27  bool IsValidKeyLength(size_t n) const
28  {return GetBlockCipher().IsValidKeyLength(n);}
29  unsigned int OptimalDataAlignment() const;
30  IV_Requirement IVRequirement() const
31  {return UNIQUE_IV;}
32  unsigned int IVSize() const
33  {return 12;}
34  unsigned int MinIVLength() const
35  {return 1;}
36  unsigned int MaxIVLength() const
37  {return UINT_MAX;} // (W64LIT(1)<<61)-1 in the standard
38  unsigned int DigestSize() const
39  {return 16;}
40  lword MaxHeaderLength() const
41  {return (W64LIT(1)<<61)-1;}
42  lword MaxMessageLength() const
43  {return ((W64LIT(1)<<39)-256)/8;}
44 
45 protected:
46  // AuthenticatedSymmetricCipherBase
47  bool AuthenticationIsOnPlaintext() const
48  {return false;}
49  unsigned int AuthenticationBlockSize() const
50  {return HASH_BLOCKSIZE;}
51  void SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs &params);
52  void Resync(const byte *iv, size_t len);
53  size_t AuthenticateBlocks(const byte *data, size_t len);
54  void AuthenticateLastHeaderBlock();
55  void AuthenticateLastConfidentialBlock();
56  void AuthenticateLastFooterBlock(byte *mac, size_t macSize);
57  SymmetricCipher & AccessSymmetricCipher() {return m_ctr;}
58 
59  virtual BlockCipher & AccessBlockCipher() =0;
60  virtual GCM_TablesOption GetTablesOption() const =0;
61 
62  const BlockCipher & GetBlockCipher() const {return const_cast<GCM_Base *>(this)->AccessBlockCipher();};
63  byte *HashBuffer() {return m_buffer+REQUIRED_BLOCKSIZE;}
64  byte *HashKey() {return m_buffer+2*REQUIRED_BLOCKSIZE;}
65  byte *MulTable() {return m_buffer+3*REQUIRED_BLOCKSIZE;}
66  inline void ReverseHashBufferIfNeeded();
67 
68  class CRYPTOPP_DLL GCTR : public CTR_Mode_ExternalCipher::Encryption
69  {
70  protected:
71  void IncrementCounterBy256();
72  };
73 
74  GCTR m_ctr;
75  static word16 s_reductionTable[256];
76  static volatile bool s_reductionTableInitialized;
77  enum {REQUIRED_BLOCKSIZE = 16, HASH_BLOCKSIZE = 16};
78 };
79 
80 //! .
81 template <class T_BlockCipher, GCM_TablesOption T_TablesOption, bool T_IsEncryption>
82 class GCM_Final : public GCM_Base
83 {
84 public:
85  static std::string StaticAlgorithmName()
86  {return T_BlockCipher::StaticAlgorithmName() + std::string("/GCM");}
88  {return T_IsEncryption;}
89 
90 private:
91  GCM_TablesOption GetTablesOption() const {return T_TablesOption;}
92  BlockCipher & AccessBlockCipher() {return m_cipher;}
93  typename T_BlockCipher::Encryption m_cipher;
94 };
95 
96 //! <a href="http://www.cryptolounge.org/wiki/GCM">GCM</a>
97 template <class T_BlockCipher, GCM_TablesOption T_TablesOption=GCM_2K_Tables>
99 {
102 };
103 
104 NAMESPACE_END
105 
106 #endif